Bug 1052052 - Hoist AutoCxPusher into ScriptSettings.h. r=gabor
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "xpcprivate.h" // For AutoCxPusher guts
|
||||
#include "xpcpublic.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
@@ -18,6 +19,7 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -373,5 +375,66 @@ AutoNoJSAPI::AutoNoJSAPI(bool aIsMainThread)
|
||||
}
|
||||
}
|
||||
|
||||
danger::AutoCxPusher::AutoCxPusher(JSContext* cx, bool allowNull)
|
||||
{
|
||||
MOZ_ASSERT_IF(!allowNull, cx);
|
||||
|
||||
// Hold a strong ref to the nsIScriptContext, if any. This ensures that we
|
||||
// only destroy the mContext of an nsJSContext when it is not on the cx stack
|
||||
// (and therefore not in use). See nsJSContext::DestroyJSContext().
|
||||
if (cx)
|
||||
mScx = GetScriptContextFromJSContext(cx);
|
||||
|
||||
XPCJSContextStack *stack = XPCJSRuntime::Get()->GetJSContextStack();
|
||||
if (!stack->Push(cx)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
mStackDepthAfterPush = stack->Count();
|
||||
|
||||
#ifdef DEBUG
|
||||
mPushedContext = cx;
|
||||
mCompartmentDepthOnEntry = cx ? js::GetEnterCompartmentDepth(cx) : 0;
|
||||
#endif
|
||||
|
||||
// Enter a request and a compartment for the duration that the cx is on the
|
||||
// stack if non-null.
|
||||
if (cx) {
|
||||
mAutoRequest.emplace(cx);
|
||||
|
||||
// DOM JSContexts don't store their default compartment object on the cx.
|
||||
JSObject *compartmentObject = mScx ? mScx->GetWindowProxy()
|
||||
: js::DefaultObjectForContextOrNull(cx);
|
||||
if (compartmentObject)
|
||||
mAutoCompartment.emplace(cx, compartmentObject);
|
||||
}
|
||||
}
|
||||
|
||||
danger::AutoCxPusher::~AutoCxPusher()
|
||||
{
|
||||
// Leave the compartment and request before popping.
|
||||
mAutoCompartment.reset();
|
||||
mAutoRequest.reset();
|
||||
|
||||
// When we push a context, we may save the frame chain and pretend like we
|
||||
// haven't entered any compartment. This gets restored on Pop(), but we can
|
||||
// run into trouble if a Push/Pop are interleaved with a
|
||||
// JSAutoEnterCompartment. Make sure the compartment depth right before we
|
||||
// pop is the same as it was right after we pushed.
|
||||
MOZ_ASSERT_IF(mPushedContext, mCompartmentDepthOnEntry ==
|
||||
js::GetEnterCompartmentDepth(mPushedContext));
|
||||
DebugOnly<JSContext*> stackTop;
|
||||
MOZ_ASSERT(mPushedContext == nsXPConnect::XPConnect()->GetCurrentJSContext());
|
||||
XPCJSRuntime::Get()->GetJSContextStack()->Pop();
|
||||
mScx = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
danger::AutoCxPusher::IsStackTop() const
|
||||
{
|
||||
uint32_t currentDepth = XPCJSRuntime::Get()->GetJSContextStack()->Count();
|
||||
MOZ_ASSERT(currentDepth >= mStackDepthAfterPush);
|
||||
return currentDepth == mStackDepthAfterPush;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
Reference in New Issue
Block a user