зеркало из https://github.com/mozilla/gecko-dev.git
Bug 460882. r+sr=mrbkap, a=blocking1.9.1
This commit is contained in:
Родитель
52f4b95e16
Коммит
9f58fa6993
|
@ -6665,48 +6665,19 @@ nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
|||
// never be called when we have no outer. But just in case, return
|
||||
// null to prevent leaking an inner window to code in a different
|
||||
// window.
|
||||
|
||||
*_retval = nsnull;
|
||||
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Return the outer window.
|
||||
|
||||
// FIXME bug 420372: Our window should always have a JS object here. It
|
||||
// doesn't because of nsJSContext::FindXPCNativeWrapperClass.
|
||||
nsresult rv;
|
||||
if (win->IsChromeWindow()) {
|
||||
// Chrome windows don't get XOW wrapping.
|
||||
JSObject *outerObj = win->GetGlobalJSObject();
|
||||
if (!outerObj) {
|
||||
NS_ASSERTION(origWin->IsOuterWindow(), "What window is this?");
|
||||
*_retval = obj;
|
||||
} else {
|
||||
*_retval = outerObj;
|
||||
}
|
||||
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
JSObject *winObj = win->GetGlobalJSObject();
|
||||
if (!winObj) {
|
||||
NS_ASSERTION(origWin->IsOuterWindow(), "What window is this?");
|
||||
*_retval = obj;
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
JSObject *scope = JS_GetScopeChain(cx);
|
||||
if (!scope) {
|
||||
*_retval = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
scope = ::JS_GetGlobalForObject(cx, scope);
|
||||
jsval v;
|
||||
rv = sXPConnect->GetXOWForObject(cx, scope, winObj, &v);
|
||||
*_retval = NS_SUCCEEDED(rv) ? JSVAL_TO_OBJECT(v) : nsnull;
|
||||
}
|
||||
JSObject *winObj = win->GetGlobalJSObject();
|
||||
if (!winObj) {
|
||||
NS_ASSERTION(origWin->IsOuterWindow(), "What window is this?");
|
||||
*_retval = obj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
*_retval = winObj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -653,7 +653,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
((sprop->attrs & JSPROP_SETTER)
|
||||
? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter),
|
||||
1, vp, vp)
|
||||
: wp->setter(cx, OBJ_THIS_OBJECT(cx, obj), userid, vp));
|
||||
: wp->setter(cx, obj, userid, vp));
|
||||
if (injectFrame) {
|
||||
/* Evil code can cause us to have an arguments object. */
|
||||
if (frame.callobj)
|
||||
|
|
|
@ -855,16 +855,18 @@ ComputeThis(JSContext *cx, JSBool lazy, jsval *argv)
|
|||
return js_ComputeGlobalThis(cx, lazy, argv);
|
||||
}
|
||||
|
||||
OBJ_TO_OUTER_OBJECT(cx, thisp);
|
||||
if (!thisp)
|
||||
return NULL;
|
||||
argv[-1] = OBJECT_TO_JSVAL(thisp);
|
||||
|
||||
if (thisp->map->ops->thisObject) {
|
||||
/* Some objects (e.g., With) delegate 'this' to another object. */
|
||||
thisp = thisp->map->ops->thisObject(cx, thisp);
|
||||
if (!thisp)
|
||||
return NULL;
|
||||
}
|
||||
OBJ_TO_OUTER_OBJECT(cx, thisp);
|
||||
if (!thisp)
|
||||
return NULL;
|
||||
argv[-1] = OBJECT_TO_JSVAL(thisp);
|
||||
argv[-1] = OBJECT_TO_JSVAL(thisp);
|
||||
}
|
||||
}
|
||||
return thisp;
|
||||
}
|
||||
|
|
|
@ -336,7 +336,7 @@ struct JSScopeProperty {
|
|||
? js_InternalGetOrSet(cx, obj, (sprop)->id, \
|
||||
OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ, \
|
||||
0, 0, vp) \
|
||||
: (sprop)->getter(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
|
||||
: (sprop)->getter(cx, obj, SPROP_USERID(sprop), vp))
|
||||
|
||||
/*
|
||||
* NB: SPROP_SET must not be called if (SPROP_HAS_STUB_SETTER(sprop) &&
|
||||
|
@ -350,7 +350,7 @@ struct JSScopeProperty {
|
|||
: ((sprop)->attrs & JSPROP_GETTER) \
|
||||
? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, \
|
||||
JSMSG_GETTER_ONLY, NULL), JS_FALSE) \
|
||||
: (sprop)->setter(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
|
||||
: (sprop)->setter(cx, obj, SPROP_USERID(sprop), vp))
|
||||
|
||||
/* Macro for common expression to test for shared permanent attributes. */
|
||||
#define SPROP_IS_SHARED_PERMANENT(sprop) \
|
||||
|
|
|
@ -405,7 +405,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
|||
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||
%}
|
||||
|
||||
[uuid(f8bf005e-3700-411c-ba0c-e018075f22a4)]
|
||||
[uuid(b2ddc328-194b-45d6-95c6-52e487438096)]
|
||||
interface nsIXPConnect : nsISupports
|
||||
{
|
||||
%{ C++
|
||||
|
@ -785,4 +785,28 @@ interface nsIXPConnect : nsISupports
|
|||
in PRUint32 flags,
|
||||
in PRUint32 interfaceCount,
|
||||
[array, size_is(interfaceCount)] in nsIIDPtr interfaceArray);
|
||||
|
||||
/**
|
||||
* Returns a XPCNativeWrapper, XPCSafeJSObjectWrapper, or
|
||||
* XPCCrossOriginWrapper for the given object based on the principal, scope,
|
||||
* and filename flags that are passed in.
|
||||
*
|
||||
* @param aJSContext
|
||||
* A JSContext.
|
||||
* @param aObject
|
||||
* The object to wrap.
|
||||
* @param aScope
|
||||
* The scope to be used in the event that we create a
|
||||
* XPCCrossOriginWrapper. Can be null.
|
||||
* @param aPrincipal
|
||||
* The principal that should be used for the wrapper.
|
||||
* @param aFilenameFlags
|
||||
* The filename flags from the script that will use this wrapper.
|
||||
*/
|
||||
[noscript] JSVal getWrapperForObject(
|
||||
in JSContextPtr aJSContext,
|
||||
in JSObjectPtr aObject,
|
||||
in JSObjectPtr aScope,
|
||||
in nsIPrincipal aPrincipal,
|
||||
in unsigned long aFilenameFlags);
|
||||
};
|
||||
|
|
|
@ -472,24 +472,31 @@ XPC_XOW_RewrapIfNeeded(JSContext *cx, JSObject *outerObj, jsval *vp)
|
|||
}
|
||||
|
||||
JSBool
|
||||
XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
|
||||
XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp,
|
||||
XPCWrappedNative* wn)
|
||||
{
|
||||
// Our argument should be a wrapped native object.
|
||||
NS_ASSERTION(XPCPerThreadData::IsMainThread(cx),
|
||||
"Can't wrap object on non-main thread!");
|
||||
|
||||
// Our argument should be a wrapped native object, but the caller may have
|
||||
// passed it in as an optimization.
|
||||
JSObject *wrappedObj;
|
||||
XPCWrappedNative *wn;
|
||||
if (!JSVAL_IS_OBJECT(*vp) ||
|
||||
!(wrappedObj = JSVAL_TO_OBJECT(*vp)) ||
|
||||
STOBJ_GET_CLASS(wrappedObj) == &sXPC_XOW_JSClass.base ||
|
||||
STOBJ_GET_CLASS(wrappedObj) == &sXPC_XOW_JSClass.base) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (!wn &&
|
||||
!(wn = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, wrappedObj))) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
|
||||
XPCCallContext ccx(NATIVE_CALLER, cx);
|
||||
NS_ENSURE_TRUE(ccx.IsValid(), JS_FALSE);
|
||||
|
||||
// The parent must be the inner global object for its scope.
|
||||
parent = JS_GetGlobalForObject(cx, parent);
|
||||
|
||||
JSClass *clasp = STOBJ_GET_CLASS(parent);
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
|
||||
|
@ -502,7 +509,7 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
|
|||
}
|
||||
|
||||
XPCWrappedNativeScope *parentScope =
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(ccx, parent);
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(cx, parent, nsnull, rt);
|
||||
|
||||
#ifdef DEBUG_mrbkap_off
|
||||
printf("Wrapping object at %p (%s) [%p]\n",
|
||||
|
@ -513,11 +520,7 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
|
|||
JSObject *outerObj = nsnull;
|
||||
WrappedNative2WrapperMap *map = parentScope->GetWrapperMap();
|
||||
|
||||
{ // Scoped lock
|
||||
XPCAutoLock al(rt->GetMapLock());
|
||||
outerObj = map->Find(wrappedObj);
|
||||
}
|
||||
|
||||
outerObj = map->Find(wrappedObj);
|
||||
if (outerObj) {
|
||||
NS_ASSERTION(STOBJ_GET_CLASS(outerObj) == &sXPC_XOW_JSClass.base,
|
||||
"What crazy object are we getting here?");
|
||||
|
@ -547,10 +550,7 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
|
|||
|
||||
*vp = OBJECT_TO_JSVAL(outerObj);
|
||||
|
||||
{ // Scoped lock
|
||||
XPCAutoLock al(rt->GetMapLock());
|
||||
map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj);
|
||||
}
|
||||
map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#include "xpcprivate.h"
|
||||
#include "XPCNativeWrapper.h"
|
||||
#include "XPCWrapper.h"
|
||||
#include "nsBaseHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "jsatom.h"
|
||||
|
@ -2304,6 +2305,71 @@ nsXPConnect::DefineDOMQuickStubs(JSContext * cx,
|
|||
interfaceCount, interfaceArray);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::GetWrapperForObject(JSContext* aJSContext,
|
||||
JSObject* aObject,
|
||||
JSObject* aScope,
|
||||
nsIPrincipal* aPrincipal,
|
||||
PRUint32 aFilenameFlags,
|
||||
jsval* _retval)
|
||||
{
|
||||
NS_ASSERTION(aFilenameFlags != JSFILENAME_NULL, "Null filename!");
|
||||
NS_ASSERTION(XPCPerThreadData::IsMainThread(aJSContext),
|
||||
"Must only be called from the main thread as these wrappers "
|
||||
"are not threadsafe!");
|
||||
|
||||
JSAutoRequest ar(aJSContext);
|
||||
|
||||
XPCWrappedNative *wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(aJSContext, aObject);
|
||||
if(!wrapper)
|
||||
{
|
||||
// Couldn't get the wrapped native (maybe a prototype?) so just return
|
||||
// the original object.
|
||||
*_retval = OBJECT_TO_JSVAL(aObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
XPCWrappedNativeScope *xpcscope =
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(aJSContext, aScope);
|
||||
if(!xpcscope)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if(STOBJ_IS_SYSTEM(aObject) ||
|
||||
(wrapper->GetScope() == xpcscope &&
|
||||
!XPC_XOW_ClassNeedsXOW(STOBJ_GET_CLASS(aObject)->name)))
|
||||
{
|
||||
*_retval = OBJECT_TO_JSVAL(aObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject* wrappedObj = nsnull;
|
||||
|
||||
if(aFilenameFlags & JSFILENAME_PROTECTED)
|
||||
{
|
||||
wrappedObj = XPCNativeWrapper::GetNewOrUsed(aJSContext, wrapper,
|
||||
aPrincipal);
|
||||
}
|
||||
else if(aFilenameFlags & JSFILENAME_SYSTEM)
|
||||
{
|
||||
jsval val = OBJECT_TO_JSVAL(aObject);
|
||||
if(XPC_SJOW_Construct(aJSContext, nsnull, 1, &val, &val))
|
||||
wrappedObj = JSVAL_TO_OBJECT(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
jsval val = OBJECT_TO_JSVAL(aObject);
|
||||
if(XPC_XOW_WrapObject(aJSContext, aScope, &val, wrapper))
|
||||
wrappedObj = JSVAL_TO_OBJECT(val);
|
||||
}
|
||||
|
||||
if(!wrappedObj)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*_retval = OBJECT_TO_JSVAL(wrappedObj);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute JSRuntime runtime; */
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::GetRuntime(JSRuntime **runtime)
|
||||
|
|
|
@ -75,8 +75,6 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
|||
if(!mXPC)
|
||||
return;
|
||||
|
||||
NS_ADDREF(mXPC);
|
||||
|
||||
mThreadData = XPCPerThreadData::GetData(mJSContext);
|
||||
|
||||
if(!mThreadData)
|
||||
|
@ -130,6 +128,11 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
|||
// hook into call context chain for our thread
|
||||
mPrevCallContext = mThreadData->SetCallContext(this);
|
||||
|
||||
// We only need to addref xpconnect once so only do it if this is the first
|
||||
// context in the chain.
|
||||
if(!mPrevCallContext)
|
||||
NS_ADDREF(mXPC);
|
||||
|
||||
mState = HAVE_CONTEXT;
|
||||
|
||||
if(!obj)
|
||||
|
@ -294,6 +297,8 @@ XPCCallContext::~XPCCallContext()
|
|||
{
|
||||
// do cleanup...
|
||||
|
||||
PRBool shouldReleaseXPC = PR_FALSE;
|
||||
|
||||
if(mXPCContext)
|
||||
{
|
||||
mXPCContext->SetCallingLangType(mPrevCallerLanguage);
|
||||
|
@ -304,6 +309,8 @@ XPCCallContext::~XPCCallContext()
|
|||
#else
|
||||
(void) mThreadData->SetCallContext(mPrevCallContext);
|
||||
#endif
|
||||
|
||||
shouldReleaseXPC = mPrevCallContext == nsnull;
|
||||
}
|
||||
|
||||
if(mContextPopRequired)
|
||||
|
@ -363,7 +370,8 @@ XPCCallContext::~XPCCallContext()
|
|||
}
|
||||
#endif
|
||||
|
||||
NS_IF_RELEASE(mXPC);
|
||||
if(shouldReleaseXPC && mXPC)
|
||||
NS_RELEASE(mXPC);
|
||||
}
|
||||
|
||||
XPCReadableJSStringWrapper *
|
||||
|
|
|
@ -1252,9 +1252,18 @@ public:
|
|||
|
||||
void RemoveWrappedNativeProtos();
|
||||
|
||||
static XPCWrappedNativeScope*
|
||||
FindInJSObjectScope(JSContext* cx, JSObject* obj,
|
||||
JSBool OKIfNotInitialized = JS_FALSE,
|
||||
XPCJSRuntime* runtime = nsnull);
|
||||
|
||||
static XPCWrappedNativeScope*
|
||||
FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
||||
JSBool OKIfNotInitialized = JS_FALSE);
|
||||
JSBool OKIfNotInitialized = JS_FALSE)
|
||||
{
|
||||
return FindInJSObjectScope(ccx, obj, OKIfNotInitialized,
|
||||
ccx.GetRuntime());
|
||||
}
|
||||
|
||||
static void
|
||||
SystemIsBeingShutDown(JSContext* cx);
|
||||
|
@ -1328,7 +1337,10 @@ private:
|
|||
XPCJSRuntime* mRuntime;
|
||||
Native2WrappedNativeMap* mWrappedNativeMap;
|
||||
ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
|
||||
|
||||
// This map should *never* be accessed from a non-main thread!
|
||||
WrappedNative2WrapperMap* mWrapperMap;
|
||||
|
||||
nsXPCComponents* mComponents;
|
||||
XPCWrappedNativeScope* mNext;
|
||||
// The JS global object for this scope. If non-null, this will be the
|
||||
|
@ -4070,7 +4082,8 @@ XPC_SJOW_AttachNewConstructorObject(XPCCallContext &ccx,
|
|||
JSObject *aGlobalObject);
|
||||
|
||||
JSBool
|
||||
XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp);
|
||||
XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp,
|
||||
XPCWrappedNative *wn = nsnull);
|
||||
|
||||
#ifdef XPC_IDISPATCH_SUPPORT
|
||||
// IDispatch specific classes
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
#include "xpcprivate.h"
|
||||
#include "XPCNativeWrapper.h"
|
||||
#include "XPCWrapper.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
@ -1275,6 +1276,110 @@ XPC_WN_JSOp_Clear(JSContext *cx, JSObject *obj)
|
|||
js_ObjectOps.clear(cx, obj);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
NS_STACK_CLASS class AutoPopJSContext
|
||||
{
|
||||
public:
|
||||
AutoPopJSContext(XPCJSContextStack *stack)
|
||||
: mCx(nsnull), mStack(stack)
|
||||
{
|
||||
NS_ASSERTION(stack, "Null stack!");
|
||||
}
|
||||
|
||||
~AutoPopJSContext()
|
||||
{
|
||||
if(mCx)
|
||||
mStack->Pop(nsnull);
|
||||
}
|
||||
|
||||
void PushIfNotTop(JSContext *cx)
|
||||
{
|
||||
NS_ASSERTION(cx, "Null context!");
|
||||
NS_ASSERTION(!mCx, "This class is only meant to be used once!");
|
||||
|
||||
JSContext *cxTop = nsnull;
|
||||
mStack->Peek(&cxTop);
|
||||
|
||||
if(cxTop != cx && NS_SUCCEEDED(mStack->Push(cx)))
|
||||
mCx = cx;
|
||||
}
|
||||
|
||||
private:
|
||||
JSContext *mCx;
|
||||
XPCJSContextStack *mStack;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static JSObject*
|
||||
XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
// None of the wrappers we could potentially hand out are threadsafe so
|
||||
// just hand out the given object.
|
||||
if(!XPCPerThreadData::IsMainThread(cx))
|
||||
return obj;
|
||||
|
||||
JSObject *scope = JS_GetScopeChain(cx);
|
||||
if(!scope)
|
||||
{
|
||||
XPCThrower::Throw(NS_ERROR_FAILURE, cx);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
scope = JS_GetGlobalForObject(cx, scope);
|
||||
|
||||
XPCPerThreadData *threadData = XPCPerThreadData::GetData(cx);
|
||||
if(!threadData)
|
||||
{
|
||||
XPCThrower::Throw(NS_ERROR_FAILURE, cx);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
AutoPopJSContext popper(threadData->GetJSContextStack());
|
||||
popper.PushIfNotTop(cx);
|
||||
|
||||
nsIScriptSecurityManager* secMan = XPCWrapper::GetSecurityManager();
|
||||
if(!secMan)
|
||||
{
|
||||
XPCThrower::Throw(NS_ERROR_FAILURE, cx);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSStackFrame *fp;
|
||||
nsIPrincipal *principal = secMan->GetCxSubjectPrincipalAndFrame(cx, &fp);
|
||||
|
||||
jsval retval = OBJECT_TO_JSVAL(obj);
|
||||
JSAutoTempValueRooter atvr(cx, retval);
|
||||
|
||||
if(principal && fp)
|
||||
{
|
||||
JSScript* script = JS_GetFrameScript(cx, fp);
|
||||
|
||||
PRUint32 flags = script ? JS_GetScriptFilenameFlags(script) : 0;
|
||||
NS_ASSERTION(flags != JSFILENAME_NULL, "Null filename!");
|
||||
|
||||
nsXPConnect *xpc = nsXPConnect::GetXPConnect();
|
||||
if(!xpc)
|
||||
{
|
||||
XPCThrower::Throw(NS_ERROR_FAILURE, cx);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
jsval val = JSVAL_VOID;
|
||||
|
||||
nsresult rv = xpc->GetWrapperForObject(cx, obj, scope, principal, flags,
|
||||
&retval);
|
||||
if(NS_FAILED(rv))
|
||||
{
|
||||
XPCThrower::Throw(rv, cx);
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
return JSVAL_TO_OBJECT(retval);
|
||||
}
|
||||
|
||||
JSObjectOps *
|
||||
XPC_WN_GetObjectOpsNoCall(JSContext *cx, JSClass *clazz)
|
||||
{
|
||||
|
@ -1293,14 +1398,15 @@ JSBool xpc_InitWrappedNativeJSOps()
|
|||
{
|
||||
memcpy(&XPC_WN_NoCall_JSOps, &js_ObjectOps, sizeof(JSObjectOps));
|
||||
XPC_WN_NoCall_JSOps.enumerate = XPC_WN_JSOp_Enumerate;
|
||||
XPC_WN_NoCall_JSOps.call = nsnull;
|
||||
XPC_WN_NoCall_JSOps.construct = nsnull;
|
||||
XPC_WN_NoCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
||||
XPC_WN_NoCall_JSOps.thisObject = XPC_WN_JSOp_ThisObject;
|
||||
|
||||
memcpy(&XPC_WN_WithCall_JSOps, &js_ObjectOps, sizeof(JSObjectOps));
|
||||
XPC_WN_WithCall_JSOps.enumerate = XPC_WN_JSOp_Enumerate;
|
||||
XPC_WN_WithCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
||||
|
||||
XPC_WN_NoCall_JSOps.call = nsnull;
|
||||
XPC_WN_NoCall_JSOps.construct = nsnull;
|
||||
XPC_WN_NoCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
||||
XPC_WN_WithCall_JSOps.thisObject = XPC_WN_JSOp_ThisObject;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -737,18 +737,19 @@ GetScopeOfObject(JSObject* obj)
|
|||
|
||||
|
||||
#ifdef DEBUG
|
||||
void DEBUG_CheckForComponentsInScope(XPCCallContext& ccx, JSObject* obj,
|
||||
JSBool OKIfNotInitialized)
|
||||
void DEBUG_CheckForComponentsInScope(JSContext* cx, JSObject* obj,
|
||||
JSBool OKIfNotInitialized,
|
||||
XPCJSRuntime* runtime)
|
||||
{
|
||||
if(OKIfNotInitialized)
|
||||
return;
|
||||
|
||||
if(!(JS_GetOptions(ccx) & JSOPTION_PRIVATE_IS_NSISUPPORTS))
|
||||
if(!(JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS))
|
||||
return;
|
||||
|
||||
const char* name = ccx.GetRuntime()->GetStringName(XPCJSRuntime::IDX_COMPONENTS);
|
||||
const char* name = runtime->GetStringName(XPCJSRuntime::IDX_COMPONENTS);
|
||||
jsval prop;
|
||||
if(JS_LookupProperty(ccx, obj, name, &prop) && !JSVAL_IS_PRIMITIVE(prop))
|
||||
if(JS_LookupProperty(cx, obj, name, &prop) && !JSVAL_IS_PRIMITIVE(prop))
|
||||
return;
|
||||
|
||||
// This is pretty much always bad. It usually means that native code is
|
||||
|
@ -764,13 +765,15 @@ void DEBUG_CheckForComponentsInScope(XPCCallContext& ccx, JSObject* obj,
|
|||
#endif
|
||||
}
|
||||
#else
|
||||
#define DEBUG_CheckForComponentsInScope(ccx, obj, OKIfNotInitialized) ((void)0)
|
||||
#define DEBUG_CheckForComponentsInScope(ccx, obj, OKIfNotInitialized, runtime) \
|
||||
((void)0)
|
||||
#endif
|
||||
|
||||
// static
|
||||
XPCWrappedNativeScope*
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
||||
JSBool OKIfNotInitialized)
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(JSContext* cx, JSObject* obj,
|
||||
JSBool OKIfNotInitialized,
|
||||
XPCJSRuntime* runtime)
|
||||
{
|
||||
XPCWrappedNativeScope* scope;
|
||||
|
||||
|
@ -786,13 +789,19 @@ XPCWrappedNativeScope::FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
|||
|
||||
// Else we'll have to look up the parent chain to get the scope
|
||||
|
||||
obj = JS_GetGlobalForObject(ccx, obj);
|
||||
obj = JS_GetGlobalForObject(cx, obj);
|
||||
|
||||
if(!runtime)
|
||||
{
|
||||
runtime = nsXPConnect::GetRuntimeInstance();
|
||||
NS_ASSERTION(runtime, "This should never be null!");
|
||||
}
|
||||
|
||||
// XXX We are assuming that the scope count is low enough that traversing
|
||||
// the linked list is more reasonable then doing a hashtable lookup.
|
||||
XPCWrappedNativeScope* found = nsnull;
|
||||
{ // scoped lock
|
||||
XPCAutoLock lock(ccx.GetRuntime()->GetMapLock());
|
||||
XPCAutoLock lock(runtime->GetMapLock());
|
||||
|
||||
DEBUG_TrackScopeTraversal();
|
||||
|
||||
|
@ -808,7 +817,7 @@ XPCWrappedNativeScope::FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
|||
|
||||
if(found) {
|
||||
// This cannot be called within the map lock!
|
||||
DEBUG_CheckForComponentsInScope(ccx, obj, OKIfNotInitialized);
|
||||
DEBUG_CheckForComponentsInScope(cx, obj, OKIfNotInitialized, runtime);
|
||||
return found;
|
||||
}
|
||||
|
||||
|
@ -819,7 +828,6 @@ XPCWrappedNativeScope::FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static JSDHashOperator
|
||||
|
|
Загрузка…
Ссылка в новой задаче