mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Be more careful pushing/popping contexts. b=352264 r=jst sr=bzbarsky/jst
This commit is contained in:
parent
2964cc44d3
commit
bb32a15350
@ -1730,7 +1730,10 @@ nsJSContext::CallEventHandler(nsISupports* aTarget, void *aScope, void *aHandler
|
||||
// in the same scope as aTarget.
|
||||
rv = ConvertSupportsTojsvals(aargv, target, &argc,
|
||||
NS_REINTERPRET_CAST(void **, &argv), &mark);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
stack->Pop(nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
AutoFreeJSStack stackGuard(mContext, mark); // ensure always freed.
|
||||
|
||||
|
@ -358,23 +358,20 @@ MozAxAutoPushJSContext::MozAxAutoPushJSContext(JSContext *cx,
|
||||
nsIURI * aURI)
|
||||
: mContext(cx), mPushResult(NS_OK)
|
||||
{
|
||||
mContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
nsCOMPtr<nsIJSContextStack> contextStack =
|
||||
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
|
||||
if(mContextStack)
|
||||
JSContext* currentCX;
|
||||
if(contextStack &&
|
||||
// Don't push if the current context is already on the stack.
|
||||
(NS_FAILED(contextStack->Peek(¤tCX)) ||
|
||||
cx != currentCX) )
|
||||
{
|
||||
JSContext* currentCX;
|
||||
if(NS_SUCCEEDED(mContextStack->Peek(¤tCX)))
|
||||
if (NS_SUCCEEDED(contextStack->Push(cx)))
|
||||
{
|
||||
// Is the current context already on the stack?
|
||||
if(cx == currentCX)
|
||||
mContextStack = nsnull;
|
||||
else
|
||||
{
|
||||
mContextStack->Push(cx);
|
||||
// Leave the reference to the mContextStack to
|
||||
// indicate that we need to pop it in our dtor.
|
||||
}
|
||||
|
||||
// Leave the reference in mContextStack to
|
||||
// indicate that we need to pop it in our dtor.
|
||||
mContextStack.swap(contextStack);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,26 +296,22 @@ JSContextAutoPopper::~JSContextAutoPopper()
|
||||
|
||||
nsresult JSContextAutoPopper::Push(JSContext *cx)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mContext) // only once
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mService = do_GetService(sJSStackContractID);
|
||||
if(mService) {
|
||||
if (cx) {
|
||||
mContext = cx;
|
||||
} else {
|
||||
rv = mService->GetSafeJSContext(&mContext);
|
||||
// Get the safe context if we're not provided one.
|
||||
if (!cx && NS_FAILED(mService->GetSafeJSContext(&cx))) {
|
||||
cx = nsnull;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && mContext) {
|
||||
rv = mService->Push(mContext);
|
||||
if (NS_FAILED(rv))
|
||||
mContext = 0;
|
||||
// Save cx in mContext to indicate need to pop.
|
||||
if (cx && NS_SUCCEEDED(mService->Push(cx))) {
|
||||
mContext = cx;
|
||||
}
|
||||
}
|
||||
return mContext ? NS_OK : NS_ERROR_FAILURE;
|
||||
return mContext ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
|
@ -110,22 +110,20 @@ AutoPushJSContext::AutoPushJSContext(nsISupports* aSecuritySupports,
|
||||
JSContext *cx)
|
||||
: mContext(cx), mPushResult(NS_OK)
|
||||
{
|
||||
mContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
nsCOMPtr<nsIJSContextStack> contextStack =
|
||||
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
|
||||
if(mContextStack)
|
||||
JSContext* currentCX;
|
||||
if(contextStack &&
|
||||
// Don't push if the current context is already on the stack.
|
||||
(NS_FAILED(contextStack->Peek(¤tCX)) ||
|
||||
cx != currentCX) )
|
||||
{
|
||||
JSContext* currentCX;
|
||||
if(NS_SUCCEEDED(mContextStack->Peek(¤tCX)))
|
||||
if (NS_SUCCEEDED(contextStack->Push(cx)))
|
||||
{
|
||||
// Is the current context already on the stack?
|
||||
if(cx == currentCX)
|
||||
mContextStack = nsnull;
|
||||
else
|
||||
{
|
||||
mContextStack->Push(cx);
|
||||
// Leave the reference to the mContextStack to
|
||||
// indicate that we need to pop it in our dtor.
|
||||
}
|
||||
// Leave the reference in mContextStack to
|
||||
// indicate that we need to pop it in our dtor.
|
||||
mContextStack.swap(contextStack);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,25 +299,6 @@ XPCCallContext::~XPCCallContext()
|
||||
{
|
||||
mXPCContext->SetCallingLangType(mPrevCallerLanguage);
|
||||
|
||||
if(mContextPopRequired)
|
||||
{
|
||||
XPCJSContextStack* stack = mThreadData->GetJSContextStack();
|
||||
if(stack)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JSContext* poppedCX;
|
||||
nsresult rv = stack->Pop(&poppedCX);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && poppedCX == mJSContext, "bad pop");
|
||||
#else
|
||||
(void) stack->Pop(nsnull);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERTION(0, "bad!");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
XPCCallContext* old = mThreadData->SetCallContext(mPrevCallContext);
|
||||
NS_ASSERTION(old == this, "bad pop from per thread data");
|
||||
@ -326,6 +307,22 @@ XPCCallContext::~XPCCallContext()
|
||||
#endif
|
||||
}
|
||||
|
||||
if(mContextPopRequired)
|
||||
{
|
||||
XPCJSContextStack* stack = mThreadData->GetJSContextStack();
|
||||
NS_ASSERTION(stack, "bad!");
|
||||
if(stack)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JSContext* poppedCX;
|
||||
nsresult rv = stack->Pop(&poppedCX);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && poppedCX == mJSContext, "bad pop");
|
||||
#else
|
||||
(void) stack->Pop(nsnull);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(mJSContext)
|
||||
{
|
||||
if(mCallerLanguage == NATIVE_CALLER && JS_GetContextThread(mJSContext))
|
||||
|
@ -1999,12 +1999,14 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
||||
NPBool bPushCaller = (result != nsnull);
|
||||
|
||||
if (bPushCaller) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIPluginInstancePeer> peer;
|
||||
if (NS_SUCCEEDED(inst->GetPeer(getter_AddRefs(peer))) && peer) {
|
||||
nsCOMPtr<nsIPluginInstancePeer2> peer2 =
|
||||
do_QueryInterface(peer, &rv);
|
||||
do_QueryInterface(peer);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && peer2) {
|
||||
if (peer2) {
|
||||
JSContext *cx;
|
||||
rv = peer2->GetJSContext(&cx);
|
||||
|
||||
|
@ -78,22 +78,6 @@ static JSRuntime *sJSRuntime;
|
||||
// while executing JS on the context.
|
||||
static nsIJSContextStack *sContextStack;
|
||||
|
||||
class AutoCXPusher
|
||||
{
|
||||
public:
|
||||
AutoCXPusher(JSContext *cx)
|
||||
{
|
||||
if (sContextStack)
|
||||
sContextStack->Push(cx);
|
||||
}
|
||||
|
||||
~AutoCXPusher()
|
||||
{
|
||||
if (sContextStack)
|
||||
sContextStack->Pop(nsnull);
|
||||
}
|
||||
};
|
||||
|
||||
NPClass nsJSObjWrapper::sJSObjWrapperNPClass =
|
||||
{
|
||||
NP_CLASS_STRUCT_VERSION,
|
||||
@ -230,6 +214,31 @@ OnWrapperDestroyed()
|
||||
}
|
||||
}
|
||||
|
||||
struct AutoCXPusher
|
||||
{
|
||||
AutoCXPusher(JSContext *cx)
|
||||
{
|
||||
// Precondition explaining why we don't need to worry about errors
|
||||
// in OnWrapperCreated.
|
||||
NS_PRECONDITION(sWrapperCount > 0,
|
||||
"must have live wrappers when using AutoCXPusher");
|
||||
|
||||
// Call OnWrapperCreated and OnWrapperDestroyed to ensure that the
|
||||
// last OnWrapperDestroyed doesn't happen while we're on the stack
|
||||
// and null out sContextStack.
|
||||
OnWrapperCreated();
|
||||
|
||||
sContextStack->Push(cx);
|
||||
}
|
||||
|
||||
~AutoCXPusher()
|
||||
{
|
||||
sContextStack->Pop(nsnull);
|
||||
|
||||
OnWrapperDestroyed();
|
||||
}
|
||||
};
|
||||
|
||||
static JSContext *
|
||||
GetJSContext(NPP npp)
|
||||
{
|
||||
|
@ -1656,18 +1656,17 @@ SafeJSContext::~SafeJSContext() {
|
||||
}
|
||||
|
||||
nsresult SafeJSContext::Push() {
|
||||
nsresult rv;
|
||||
|
||||
if (mContext) // only once
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mService = do_GetService(sJSStackContractID);
|
||||
if(mService) {
|
||||
rv = mService->GetSafeJSContext(&mContext);
|
||||
if (NS_SUCCEEDED(rv) && mContext) {
|
||||
rv = mService->Push(mContext);
|
||||
if (NS_FAILED(rv))
|
||||
mContext = 0;
|
||||
JSContext *cx;
|
||||
if (NS_SUCCEEDED(mService->GetSafeJSContext(&cx)) &&
|
||||
cx &&
|
||||
NS_SUCCEEDED(mService->Push(cx))) {
|
||||
// Save cx in mContext to indicate need to pop.
|
||||
mContext = cx;
|
||||
}
|
||||
}
|
||||
return mContext ? NS_OK : NS_ERROR_FAILURE;
|
||||
|
@ -1512,18 +1512,17 @@ SafeJSContext::~SafeJSContext() {
|
||||
}
|
||||
|
||||
nsresult SafeJSContext::Push() {
|
||||
nsresult rv;
|
||||
|
||||
if (mContext) // only once
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mService = do_GetService(sJSStackContractID);
|
||||
if(mService) {
|
||||
rv = mService->GetSafeJSContext(&mContext);
|
||||
if (NS_SUCCEEDED(rv) && mContext) {
|
||||
rv = mService->Push(mContext);
|
||||
if (NS_FAILED(rv))
|
||||
mContext = 0;
|
||||
JSContext *cx;
|
||||
if (NS_SUCCEEDED(mService->GetSafeJSContext(&cx)) &&
|
||||
cx &&
|
||||
NS_SUCCEEDED(mService->Push(cx))) {
|
||||
// Save cx in mContext to indicate need to pop.
|
||||
mContext = cx;
|
||||
}
|
||||
}
|
||||
return mContext ? NS_OK : NS_ERROR_FAILURE;
|
||||
|
@ -2300,21 +2300,20 @@ SafeJSContext::~SafeJSContext() {
|
||||
}
|
||||
|
||||
nsresult SafeJSContext::Push() {
|
||||
nsresult rv;
|
||||
|
||||
if (mContext) // only once
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mService = do_GetService(sJSStackContractID);
|
||||
if(mService) {
|
||||
rv = mService->GetSafeJSContext(&mContext);
|
||||
if (NS_SUCCEEDED(rv) && mContext) {
|
||||
rv = mService->Push(mContext);
|
||||
if (NS_FAILED(rv))
|
||||
mContext = 0;
|
||||
JSContext *cx;
|
||||
if (NS_SUCCEEDED(mService->GetSafeJSContext(&cx)) &&
|
||||
cx &&
|
||||
NS_SUCCEEDED(mService->Push(cx))) {
|
||||
// Save cx in mContext to indicate need to pop.
|
||||
mContext = cx;
|
||||
}
|
||||
}
|
||||
return mContext ? NS_OK : NS_ERROR_FAILURE;
|
||||
return mContext ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2314,18 +2314,17 @@ SafeJSContext::~SafeJSContext() {
|
||||
}
|
||||
|
||||
nsresult SafeJSContext::Push() {
|
||||
nsresult rv;
|
||||
|
||||
if (mContext) // only once
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mService = do_GetService(sJSStackContractID);
|
||||
if(mService) {
|
||||
rv = mService->GetSafeJSContext(&mContext);
|
||||
if (NS_SUCCEEDED(rv) && mContext) {
|
||||
rv = mService->Push(mContext);
|
||||
if (NS_FAILED(rv))
|
||||
mContext = 0;
|
||||
JSContext *cx;
|
||||
if (NS_SUCCEEDED(mService->GetSafeJSContext(&cx)) &&
|
||||
cx &&
|
||||
NS_SUCCEEDED(mService->Push(cx))) {
|
||||
// Save cx in mContext to indicate need to pop.
|
||||
mContext = cx;
|
||||
}
|
||||
}
|
||||
return mContext ? NS_OK : NS_ERROR_FAILURE;
|
||||
|
Loading…
Reference in New Issue
Block a user