mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
When pushing on top of a JSContext on the XPConnect JSContext stack, save offthe JSStackFrame chain on that JSContext. When popping, restore the stackframe chain. Bug 371858, r=jst, sr=brendan
This commit is contained in:
parent
b1563bdb95
commit
5a7814a82a
@ -108,6 +108,7 @@
|
||||
#include "nsIPropertyBag.h"
|
||||
#include "nsIProperty.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "nsIXPCScriptNotify.h" // used to notify: ScriptEvaluated
|
||||
|
||||
@ -2772,6 +2773,15 @@ private:
|
||||
/***************************************************************************/
|
||||
// XPCJSContextStack is not actually an xpcom object, but xpcom calls are
|
||||
// delegated to it as an implementation detail.
|
||||
struct JSContextAndFrame {
|
||||
JSContextAndFrame(JSContext* aCx) :
|
||||
cx(aCx),
|
||||
frame(nsnull)
|
||||
{}
|
||||
JSContext* cx;
|
||||
JSStackFrame* frame; // Frame to be restored when this JSContext becomes
|
||||
// the topmost one.
|
||||
};
|
||||
|
||||
class XPCJSContextStack
|
||||
{
|
||||
@ -2786,14 +2796,14 @@ public:
|
||||
JSBool DEBUG_StackHasJSContext(JSContext* aJSContext);
|
||||
#endif
|
||||
|
||||
const nsDeque &GetStack()
|
||||
{ return mStack; }
|
||||
const nsTArray<JSContextAndFrame>* GetStack()
|
||||
{ return &mStack; }
|
||||
|
||||
private:
|
||||
void SyncJSContexts();
|
||||
|
||||
private:
|
||||
nsDeque mStack;
|
||||
nsTArray<JSContextAndFrame> mStack;
|
||||
JSContext* mSafeJSContext;
|
||||
|
||||
// If non-null, we own it; same as mSafeJSContext if SetSafeJSContext
|
||||
@ -2814,8 +2824,8 @@ public:
|
||||
NS_DECL_NSIJSCONTEXTSTACKITERATOR
|
||||
|
||||
private:
|
||||
// XXX These don't really want to be pointers.
|
||||
nsAutoPtr<nsDequeIterator> mIterator;
|
||||
const nsTArray<JSContextAndFrame> *mStack;
|
||||
PRUint32 mPosition;
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
|
@ -46,7 +46,7 @@
|
||||
/***************************************************************************/
|
||||
|
||||
XPCJSContextStack::XPCJSContextStack()
|
||||
: mStack(nsnull),
|
||||
: mStack(),
|
||||
mSafeJSContext(nsnull),
|
||||
mOwnSafeJSContext(nsnull)
|
||||
{
|
||||
@ -76,7 +76,7 @@ XPCJSContextStack::SyncJSContexts()
|
||||
NS_IMETHODIMP
|
||||
XPCJSContextStack::GetCount(PRInt32 *aCount)
|
||||
{
|
||||
*aCount = mStack.GetSize();
|
||||
*aCount = mStack.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ XPCJSContextStack::GetCount(PRInt32 *aCount)
|
||||
NS_IMETHODIMP
|
||||
XPCJSContextStack::Peek(JSContext * *_retval)
|
||||
{
|
||||
*_retval = (JSContext*) mStack.Peek();
|
||||
*_retval = mStack.IsEmpty() ? nsnull : mStack[mStack.Length() - 1].cx;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -92,12 +92,28 @@ XPCJSContextStack::Peek(JSContext * *_retval)
|
||||
NS_IMETHODIMP
|
||||
XPCJSContextStack::Pop(JSContext * *_retval)
|
||||
{
|
||||
NS_ASSERTION(mStack.GetSize() > 0, "ThreadJSContextStack underflow");
|
||||
NS_ASSERTION(!mStack.IsEmpty(), "ThreadJSContextStack underflow");
|
||||
|
||||
PRUint32 idx = mStack.Length() - 1; // The thing we're popping
|
||||
NS_ASSERTION(!mStack[idx].frame,
|
||||
"Shouldn't have a pending frame to restore on the context "
|
||||
"we're popping!");
|
||||
|
||||
if(_retval)
|
||||
*_retval = (JSContext*) mStack.Pop();
|
||||
else
|
||||
mStack.Pop();
|
||||
*_retval = mStack[idx].cx;
|
||||
|
||||
mStack.RemoveElementAt(idx);
|
||||
if(idx > 0)
|
||||
{
|
||||
--idx; // Advance to new top of the stack
|
||||
JSContextAndFrame & e = mStack[idx];
|
||||
NS_ASSERTION(!e.frame || e.cx, "Shouldn't have frame without a cx!");
|
||||
if(e.cx)
|
||||
{
|
||||
JS_RestoreFrameChain(e.cx, e.frame);
|
||||
e.frame = nsnull;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -105,7 +121,14 @@ XPCJSContextStack::Pop(JSContext * *_retval)
|
||||
NS_IMETHODIMP
|
||||
XPCJSContextStack::Push(JSContext * cx)
|
||||
{
|
||||
mStack.Push(cx);
|
||||
if(!mStack.AppendElement(cx))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if(mStack.Length() > 1)
|
||||
{
|
||||
JSContextAndFrame & e = mStack[mStack.Length() - 2];
|
||||
if(e.cx)
|
||||
e.frame = JS_SaveFrameChain(e.cx);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -113,8 +136,8 @@ XPCJSContextStack::Push(JSContext * cx)
|
||||
JSBool
|
||||
XPCJSContextStack::DEBUG_StackHasJSContext(JSContext* aJSContext)
|
||||
{
|
||||
for(PRInt32 i = 0; i < mStack.GetSize(); i++)
|
||||
if(aJSContext == (JSContext*)mStack.ObjectAt(i))
|
||||
for(PRUint32 i = 0; i < mStack.Length(); i++)
|
||||
if(aJSContext == mStack[i].cx)
|
||||
return JS_TRUE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -643,17 +666,11 @@ nsXPCJSContextStackIterator::Reset(nsIJSContextStack *aStack)
|
||||
XPCJSContextStack *stack = impl->GetStackForCurrentThread();
|
||||
if(!stack)
|
||||
return NS_ERROR_FAILURE;
|
||||
const nsDeque &deque = stack->GetStack();
|
||||
|
||||
if(deque.GetSize() == 0)
|
||||
{
|
||||
mIterator = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mIterator = new nsDequeIterator(deque.End());
|
||||
if(!mIterator)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mStack = stack->GetStack();
|
||||
if(mStack->IsEmpty())
|
||||
mStack = nsnull;
|
||||
else
|
||||
mPosition = mStack->Length() - 1;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -661,25 +678,23 @@ nsXPCJSContextStackIterator::Reset(nsIJSContextStack *aStack)
|
||||
NS_IMETHODIMP
|
||||
nsXPCJSContextStackIterator::Done(PRBool *aDone)
|
||||
{
|
||||
*aDone = !mIterator;
|
||||
*aDone = !mStack;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCJSContextStackIterator::Prev(JSContext **aContext)
|
||||
{
|
||||
if(!mIterator)
|
||||
if(!mStack)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aContext = (JSContext*)(mIterator->GetCurrent());
|
||||
*aContext = mStack->ElementAt(mPosition).cx;
|
||||
|
||||
// XXX This temporary shouldn't be necessary.
|
||||
nsDequeIterator first(*mIterator);
|
||||
if(*mIterator == first.First())
|
||||
mIterator = nsnull;
|
||||
if(mPosition == 0)
|
||||
mStack = nsnull;
|
||||
else
|
||||
--*mIterator;
|
||||
|
||||
--mPosition;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user