зеркало из 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
|
// 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
|
// null to prevent leaking an inner window to code in a different
|
||||||
// window.
|
// window.
|
||||||
|
|
||||||
*_retval = nsnull;
|
*_retval = nsnull;
|
||||||
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the outer window.
|
JSObject *winObj = win->GetGlobalJSObject();
|
||||||
|
if (!winObj) {
|
||||||
// FIXME bug 420372: Our window should always have a JS object here. It
|
NS_ASSERTION(origWin->IsOuterWindow(), "What window is this?");
|
||||||
// doesn't because of nsJSContext::FindXPCNativeWrapperClass.
|
*_retval = obj;
|
||||||
nsresult rv;
|
return NS_OK;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
*_retval = winObj;
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -653,7 +653,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||||
((sprop->attrs & JSPROP_SETTER)
|
((sprop->attrs & JSPROP_SETTER)
|
||||||
? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter),
|
? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter),
|
||||||
1, vp, vp)
|
1, vp, vp)
|
||||||
: wp->setter(cx, OBJ_THIS_OBJECT(cx, obj), userid, vp));
|
: wp->setter(cx, obj, userid, vp));
|
||||||
if (injectFrame) {
|
if (injectFrame) {
|
||||||
/* Evil code can cause us to have an arguments object. */
|
/* Evil code can cause us to have an arguments object. */
|
||||||
if (frame.callobj)
|
if (frame.callobj)
|
||||||
|
|
|
@ -855,16 +855,18 @@ ComputeThis(JSContext *cx, JSBool lazy, jsval *argv)
|
||||||
return js_ComputeGlobalThis(cx, lazy, 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) {
|
if (thisp->map->ops->thisObject) {
|
||||||
/* Some objects (e.g., With) delegate 'this' to another object. */
|
/* Some objects (e.g., With) delegate 'this' to another object. */
|
||||||
thisp = thisp->map->ops->thisObject(cx, thisp);
|
thisp = thisp->map->ops->thisObject(cx, thisp);
|
||||||
if (!thisp)
|
if (!thisp)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
argv[-1] = OBJECT_TO_JSVAL(thisp);
|
||||||
OBJ_TO_OUTER_OBJECT(cx, thisp);
|
}
|
||||||
if (!thisp)
|
|
||||||
return NULL;
|
|
||||||
argv[-1] = OBJECT_TO_JSVAL(thisp);
|
|
||||||
}
|
}
|
||||||
return thisp;
|
return thisp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,7 +336,7 @@ struct JSScopeProperty {
|
||||||
? js_InternalGetOrSet(cx, obj, (sprop)->id, \
|
? js_InternalGetOrSet(cx, obj, (sprop)->id, \
|
||||||
OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ, \
|
OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ, \
|
||||||
0, 0, vp) \
|
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) &&
|
* NB: SPROP_SET must not be called if (SPROP_HAS_STUB_SETTER(sprop) &&
|
||||||
|
@ -350,7 +350,7 @@ struct JSScopeProperty {
|
||||||
: ((sprop)->attrs & JSPROP_GETTER) \
|
: ((sprop)->attrs & JSPROP_GETTER) \
|
||||||
? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, \
|
? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, \
|
||||||
JSMSG_GETTER_ONLY, NULL), JS_FALSE) \
|
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. */
|
/* Macro for common expression to test for shared permanent attributes. */
|
||||||
#define SPROP_IS_SHARED_PERMANENT(sprop) \
|
#define SPROP_IS_SHARED_PERMANENT(sprop) \
|
||||||
|
|
|
@ -405,7 +405,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
||||||
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||||
%}
|
%}
|
||||||
|
|
||||||
[uuid(f8bf005e-3700-411c-ba0c-e018075f22a4)]
|
[uuid(b2ddc328-194b-45d6-95c6-52e487438096)]
|
||||||
interface nsIXPConnect : nsISupports
|
interface nsIXPConnect : nsISupports
|
||||||
{
|
{
|
||||||
%{ C++
|
%{ C++
|
||||||
|
@ -785,4 +785,28 @@ interface nsIXPConnect : nsISupports
|
||||||
in PRUint32 flags,
|
in PRUint32 flags,
|
||||||
in PRUint32 interfaceCount,
|
in PRUint32 interfaceCount,
|
||||||
[array, size_is(interfaceCount)] in nsIIDPtr interfaceArray);
|
[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
|
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;
|
JSObject *wrappedObj;
|
||||||
XPCWrappedNative *wn;
|
|
||||||
if (!JSVAL_IS_OBJECT(*vp) ||
|
if (!JSVAL_IS_OBJECT(*vp) ||
|
||||||
!(wrappedObj = JSVAL_TO_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))) {
|
!(wn = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, wrappedObj))) {
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
|
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.
|
// The parent must be the inner global object for its scope.
|
||||||
parent = JS_GetGlobalForObject(cx, parent);
|
parent = JS_GetGlobalForObject(cx, parent);
|
||||||
|
|
||||||
JSClass *clasp = STOBJ_GET_CLASS(parent);
|
JSClass *clasp = STOBJ_GET_CLASS(parent);
|
||||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||||
JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
|
JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
|
||||||
|
@ -502,7 +509,7 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
|
||||||
}
|
}
|
||||||
|
|
||||||
XPCWrappedNativeScope *parentScope =
|
XPCWrappedNativeScope *parentScope =
|
||||||
XPCWrappedNativeScope::FindInJSObjectScope(ccx, parent);
|
XPCWrappedNativeScope::FindInJSObjectScope(cx, parent, nsnull, rt);
|
||||||
|
|
||||||
#ifdef DEBUG_mrbkap_off
|
#ifdef DEBUG_mrbkap_off
|
||||||
printf("Wrapping object at %p (%s) [%p]\n",
|
printf("Wrapping object at %p (%s) [%p]\n",
|
||||||
|
@ -513,11 +520,7 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
|
||||||
JSObject *outerObj = nsnull;
|
JSObject *outerObj = nsnull;
|
||||||
WrappedNative2WrapperMap *map = parentScope->GetWrapperMap();
|
WrappedNative2WrapperMap *map = parentScope->GetWrapperMap();
|
||||||
|
|
||||||
{ // Scoped lock
|
outerObj = map->Find(wrappedObj);
|
||||||
XPCAutoLock al(rt->GetMapLock());
|
|
||||||
outerObj = map->Find(wrappedObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outerObj) {
|
if (outerObj) {
|
||||||
NS_ASSERTION(STOBJ_GET_CLASS(outerObj) == &sXPC_XOW_JSClass.base,
|
NS_ASSERTION(STOBJ_GET_CLASS(outerObj) == &sXPC_XOW_JSClass.base,
|
||||||
"What crazy object are we getting here?");
|
"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);
|
*vp = OBJECT_TO_JSVAL(outerObj);
|
||||||
|
|
||||||
{ // Scoped lock
|
map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj);
|
||||||
XPCAutoLock al(rt->GetMapLock());
|
|
||||||
map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
|
|
||||||
#include "xpcprivate.h"
|
#include "xpcprivate.h"
|
||||||
#include "XPCNativeWrapper.h"
|
#include "XPCNativeWrapper.h"
|
||||||
|
#include "XPCWrapper.h"
|
||||||
#include "nsBaseHashtable.h"
|
#include "nsBaseHashtable.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "jsatom.h"
|
#include "jsatom.h"
|
||||||
|
@ -2304,6 +2305,71 @@ nsXPConnect::DefineDOMQuickStubs(JSContext * cx,
|
||||||
interfaceCount, interfaceArray);
|
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; */
|
/* attribute JSRuntime runtime; */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXPConnect::GetRuntime(JSRuntime **runtime)
|
nsXPConnect::GetRuntime(JSRuntime **runtime)
|
||||||
|
|
|
@ -75,8 +75,6 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
||||||
if(!mXPC)
|
if(!mXPC)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NS_ADDREF(mXPC);
|
|
||||||
|
|
||||||
mThreadData = XPCPerThreadData::GetData(mJSContext);
|
mThreadData = XPCPerThreadData::GetData(mJSContext);
|
||||||
|
|
||||||
if(!mThreadData)
|
if(!mThreadData)
|
||||||
|
@ -130,6 +128,11 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
||||||
// hook into call context chain for our thread
|
// hook into call context chain for our thread
|
||||||
mPrevCallContext = mThreadData->SetCallContext(this);
|
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;
|
mState = HAVE_CONTEXT;
|
||||||
|
|
||||||
if(!obj)
|
if(!obj)
|
||||||
|
@ -294,6 +297,8 @@ XPCCallContext::~XPCCallContext()
|
||||||
{
|
{
|
||||||
// do cleanup...
|
// do cleanup...
|
||||||
|
|
||||||
|
PRBool shouldReleaseXPC = PR_FALSE;
|
||||||
|
|
||||||
if(mXPCContext)
|
if(mXPCContext)
|
||||||
{
|
{
|
||||||
mXPCContext->SetCallingLangType(mPrevCallerLanguage);
|
mXPCContext->SetCallingLangType(mPrevCallerLanguage);
|
||||||
|
@ -304,6 +309,8 @@ XPCCallContext::~XPCCallContext()
|
||||||
#else
|
#else
|
||||||
(void) mThreadData->SetCallContext(mPrevCallContext);
|
(void) mThreadData->SetCallContext(mPrevCallContext);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
shouldReleaseXPC = mPrevCallContext == nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mContextPopRequired)
|
if(mContextPopRequired)
|
||||||
|
@ -363,7 +370,8 @@ XPCCallContext::~XPCCallContext()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NS_IF_RELEASE(mXPC);
|
if(shouldReleaseXPC && mXPC)
|
||||||
|
NS_RELEASE(mXPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
XPCReadableJSStringWrapper *
|
XPCReadableJSStringWrapper *
|
||||||
|
|
|
@ -1252,9 +1252,18 @@ public:
|
||||||
|
|
||||||
void RemoveWrappedNativeProtos();
|
void RemoveWrappedNativeProtos();
|
||||||
|
|
||||||
|
static XPCWrappedNativeScope*
|
||||||
|
FindInJSObjectScope(JSContext* cx, JSObject* obj,
|
||||||
|
JSBool OKIfNotInitialized = JS_FALSE,
|
||||||
|
XPCJSRuntime* runtime = nsnull);
|
||||||
|
|
||||||
static XPCWrappedNativeScope*
|
static XPCWrappedNativeScope*
|
||||||
FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
||||||
JSBool OKIfNotInitialized = JS_FALSE);
|
JSBool OKIfNotInitialized = JS_FALSE)
|
||||||
|
{
|
||||||
|
return FindInJSObjectScope(ccx, obj, OKIfNotInitialized,
|
||||||
|
ccx.GetRuntime());
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SystemIsBeingShutDown(JSContext* cx);
|
SystemIsBeingShutDown(JSContext* cx);
|
||||||
|
@ -1328,7 +1337,10 @@ private:
|
||||||
XPCJSRuntime* mRuntime;
|
XPCJSRuntime* mRuntime;
|
||||||
Native2WrappedNativeMap* mWrappedNativeMap;
|
Native2WrappedNativeMap* mWrappedNativeMap;
|
||||||
ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
|
ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
|
||||||
|
|
||||||
|
// This map should *never* be accessed from a non-main thread!
|
||||||
WrappedNative2WrapperMap* mWrapperMap;
|
WrappedNative2WrapperMap* mWrapperMap;
|
||||||
|
|
||||||
nsXPCComponents* mComponents;
|
nsXPCComponents* mComponents;
|
||||||
XPCWrappedNativeScope* mNext;
|
XPCWrappedNativeScope* mNext;
|
||||||
// The JS global object for this scope. If non-null, this will be the
|
// 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);
|
JSObject *aGlobalObject);
|
||||||
|
|
||||||
JSBool
|
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
|
#ifdef XPC_IDISPATCH_SUPPORT
|
||||||
// IDispatch specific classes
|
// IDispatch specific classes
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
|
|
||||||
#include "xpcprivate.h"
|
#include "xpcprivate.h"
|
||||||
#include "XPCNativeWrapper.h"
|
#include "XPCNativeWrapper.h"
|
||||||
|
#include "XPCWrapper.h"
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
@ -1275,6 +1276,110 @@ XPC_WN_JSOp_Clear(JSContext *cx, JSObject *obj)
|
||||||
js_ObjectOps.clear(cx, 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 *
|
JSObjectOps *
|
||||||
XPC_WN_GetObjectOpsNoCall(JSContext *cx, JSClass *clazz)
|
XPC_WN_GetObjectOpsNoCall(JSContext *cx, JSClass *clazz)
|
||||||
{
|
{
|
||||||
|
@ -1293,14 +1398,15 @@ JSBool xpc_InitWrappedNativeJSOps()
|
||||||
{
|
{
|
||||||
memcpy(&XPC_WN_NoCall_JSOps, &js_ObjectOps, sizeof(JSObjectOps));
|
memcpy(&XPC_WN_NoCall_JSOps, &js_ObjectOps, sizeof(JSObjectOps));
|
||||||
XPC_WN_NoCall_JSOps.enumerate = XPC_WN_JSOp_Enumerate;
|
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));
|
memcpy(&XPC_WN_WithCall_JSOps, &js_ObjectOps, sizeof(JSObjectOps));
|
||||||
XPC_WN_WithCall_JSOps.enumerate = XPC_WN_JSOp_Enumerate;
|
XPC_WN_WithCall_JSOps.enumerate = XPC_WN_JSOp_Enumerate;
|
||||||
XPC_WN_WithCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
XPC_WN_WithCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
||||||
|
XPC_WN_WithCall_JSOps.thisObject = XPC_WN_JSOp_ThisObject;
|
||||||
XPC_WN_NoCall_JSOps.call = nsnull;
|
|
||||||
XPC_WN_NoCall_JSOps.construct = nsnull;
|
|
||||||
XPC_WN_NoCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
|
||||||
}
|
}
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -737,18 +737,19 @@ GetScopeOfObject(JSObject* obj)
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void DEBUG_CheckForComponentsInScope(XPCCallContext& ccx, JSObject* obj,
|
void DEBUG_CheckForComponentsInScope(JSContext* cx, JSObject* obj,
|
||||||
JSBool OKIfNotInitialized)
|
JSBool OKIfNotInitialized,
|
||||||
|
XPCJSRuntime* runtime)
|
||||||
{
|
{
|
||||||
if(OKIfNotInitialized)
|
if(OKIfNotInitialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!(JS_GetOptions(ccx) & JSOPTION_PRIVATE_IS_NSISUPPORTS))
|
if(!(JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char* name = ccx.GetRuntime()->GetStringName(XPCJSRuntime::IDX_COMPONENTS);
|
const char* name = runtime->GetStringName(XPCJSRuntime::IDX_COMPONENTS);
|
||||||
jsval prop;
|
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;
|
return;
|
||||||
|
|
||||||
// This is pretty much always bad. It usually means that native code is
|
// 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
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define DEBUG_CheckForComponentsInScope(ccx, obj, OKIfNotInitialized) ((void)0)
|
#define DEBUG_CheckForComponentsInScope(ccx, obj, OKIfNotInitialized, runtime) \
|
||||||
|
((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// static
|
// static
|
||||||
XPCWrappedNativeScope*
|
XPCWrappedNativeScope*
|
||||||
XPCWrappedNativeScope::FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
XPCWrappedNativeScope::FindInJSObjectScope(JSContext* cx, JSObject* obj,
|
||||||
JSBool OKIfNotInitialized)
|
JSBool OKIfNotInitialized,
|
||||||
|
XPCJSRuntime* runtime)
|
||||||
{
|
{
|
||||||
XPCWrappedNativeScope* scope;
|
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
|
// 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
|
// XXX We are assuming that the scope count is low enough that traversing
|
||||||
// the linked list is more reasonable then doing a hashtable lookup.
|
// the linked list is more reasonable then doing a hashtable lookup.
|
||||||
XPCWrappedNativeScope* found = nsnull;
|
XPCWrappedNativeScope* found = nsnull;
|
||||||
{ // scoped lock
|
{ // scoped lock
|
||||||
XPCAutoLock lock(ccx.GetRuntime()->GetMapLock());
|
XPCAutoLock lock(runtime->GetMapLock());
|
||||||
|
|
||||||
DEBUG_TrackScopeTraversal();
|
DEBUG_TrackScopeTraversal();
|
||||||
|
|
||||||
|
@ -808,7 +817,7 @@ XPCWrappedNativeScope::FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
||||||
|
|
||||||
if(found) {
|
if(found) {
|
||||||
// This cannot be called within the map lock!
|
// This cannot be called within the map lock!
|
||||||
DEBUG_CheckForComponentsInScope(ccx, obj, OKIfNotInitialized);
|
DEBUG_CheckForComponentsInScope(cx, obj, OKIfNotInitialized, runtime);
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,7 +828,6 @@ XPCWrappedNativeScope::FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static JSDHashOperator
|
static JSDHashOperator
|
||||||
|
|
Загрузка…
Ссылка в новой задаче