Bug 968335 - Add an API to determine if a given AutoCxPusher corresponds to the stack-top cx push. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Fri, 14 Feb 2014 22:36:43 -0800
changeset 169271 b4c42334f112acc44a8330bdeb098cfd1762bc41
parent 169270 ccf60cc8004bc4f7ccc6bdc874eb4453612b2d1f
child 169272 feacaec8b46307db6ca68d8d5682513ab8cd2078
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersbz
bugs968335
milestone30.0a1
Bug 968335 - Add an API to determine if a given AutoCxPusher corresponds to the stack-top cx push. r=bz This patch, and those following, are part of an epic quest to make this API work properly despite the fact that we don't yet have GetEntryGlobal. See the comment a few patches forward.
js/xpconnect/src/nsCxPusher.cpp
js/xpconnect/src/nsCxPusher.h
--- a/js/xpconnect/src/nsCxPusher.cpp
+++ b/js/xpconnect/src/nsCxPusher.cpp
@@ -110,16 +110,17 @@ AutoCxPusher::AutoCxPusher(JSContext* cx
   // (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.
@@ -158,16 +159,24 @@ AutoCxPusher::~AutoCxPusher()
   MOZ_ASSERT_IF(mPushedContext, mCompartmentDepthOnEntry ==
                                 js::GetEnterCompartmentDepth(mPushedContext));
   DebugOnly<JSContext*> stackTop;
   MOZ_ASSERT(mPushedContext == nsXPConnect::XPConnect()->GetCurrentJSContext());
   XPCJSRuntime::Get()->GetJSContextStack()->Pop();
   mScx = nullptr;
 }
 
+bool
+AutoCxPusher::IsStackTop()
+{
+  uint32_t currentDepth = XPCJSRuntime::Get()->GetJSContextStack()->Count();
+  MOZ_ASSERT(currentDepth >= mStackDepthAfterPush);
+  return currentDepth == mStackDepthAfterPush;
+}
+
 AutoJSContext::AutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
   : mCx(nullptr)
 {
   Init(false MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT);
 }
 
 AutoJSContext::AutoJSContext(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
   : mCx(nullptr)
--- a/js/xpconnect/src/nsCxPusher.h
+++ b/js/xpconnect/src/nsCxPusher.h
@@ -26,20 +26,25 @@ class MOZ_STACK_CLASS AutoCxPusher
 {
 public:
   AutoCxPusher(JSContext *aCx, bool aAllowNull = false);
   // XPCShell uses an nsCxPusher, which contains an AutoCxPusher.
   NS_EXPORT ~AutoCxPusher();
 
   nsIScriptContext* GetScriptContext() { return mScx; }
 
+  // Returns true if this AutoCxPusher performed the push that is currently at
+  // the top of the cx stack.
+  bool IsStackTop();
+
 private:
   mozilla::Maybe<JSAutoRequest> mAutoRequest;
   mozilla::Maybe<JSAutoCompartment> mAutoCompartment;
   nsCOMPtr<nsIScriptContext> mScx;
+  uint32_t mStackDepthAfterPush;
 #ifdef DEBUG
   JSContext* mPushedContext;
   unsigned mCompartmentDepthOnEntry;
 #endif
 };
 
 } /* namespace mozilla */