js/xpconnect/src/nsCxPusher.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef nsCxPusher_h
     8 #define nsCxPusher_h
    10 #include "jsapi.h"
    11 #include "mozilla/Maybe.h"
    12 #include "nsCOMPtr.h"
    14 namespace mozilla {
    15 namespace dom {
    16 class EventTarget;
    17 }
    18 }
    20 class nsIScriptContext;
    22 namespace mozilla {
    24 /**
    25  * Fundamental cx pushing class. All other cx pushing classes are implemented
    26  * in terms of this class.
    27  */
    28 class MOZ_STACK_CLASS AutoCxPusher
    29 {
    30 public:
    31   AutoCxPusher(JSContext *aCx, bool aAllowNull = false);
    32   // XPCShell uses an nsCxPusher, which contains an AutoCxPusher.
    33   ~AutoCxPusher();
    35   nsIScriptContext* GetScriptContext() { return mScx; }
    37   // Returns true if this AutoCxPusher performed the push that is currently at
    38   // the top of the cx stack.
    39   bool IsStackTop();
    41 private:
    42   mozilla::Maybe<JSAutoRequest> mAutoRequest;
    43   mozilla::Maybe<JSAutoCompartment> mAutoCompartment;
    44   nsCOMPtr<nsIScriptContext> mScx;
    45   uint32_t mStackDepthAfterPush;
    46 #ifdef DEBUG
    47   JSContext* mPushedContext;
    48   unsigned mCompartmentDepthOnEntry;
    49 #endif
    50 };
    52 } /* namespace mozilla */
    54 /**
    55  * Legacy cx pushing class.
    56  *
    57  * This class provides a rather wonky interface, with the following quirks:
    58  *   * The constructor is a no-op, and callers must explicitly call one of
    59  *     the Push() methods.
    60  *   * Null must be pushed with PushNull().
    61  *   * The cx pusher can be reused multiple times with RePush().
    62  *
    63  * This class implements this interface in terms of the much simpler
    64  * AutoCxPusher class below.
    65  */
    66 class MOZ_STACK_CLASS nsCxPusher
    67 {
    68 public:
    69   // Returns false if something erroneous happened.
    70   bool Push(mozilla::dom::EventTarget *aCurrentTarget);
    71   // If nothing has been pushed to stack, this works like Push.
    72   // Otherwise if context will change, Pop and Push will be called.
    73   bool RePush(mozilla::dom::EventTarget *aCurrentTarget);
    74   // If a null JSContext is passed to Push(), that will cause no
    75   // push to happen and false to be returned.
    76   void Push(JSContext *cx);
    77   // Explicitly push a null JSContext on the the stack
    78   void PushNull();
    80   // Pop() will be a no-op if Push() or PushNull() fail
    81   void Pop();
    83   nsIScriptContext* GetCurrentScriptContext() {
    84     return mPusher.empty() ? nullptr : mPusher.ref().GetScriptContext();
    85   }
    87 private:
    88   mozilla::Maybe<mozilla::AutoCxPusher> mPusher;
    89 };
    91 namespace mozilla {
    93 /**
    94  * Use AutoJSContext when you need a JS context on the stack but don't have one
    95  * passed as a parameter. AutoJSContext will take care of finding the most
    96  * appropriate JS context and release it when leaving the stack.
    97  */
    98 class MOZ_STACK_CLASS AutoJSContext {
    99 public:
   100   AutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
   101   operator JSContext*() const;
   103 protected:
   104   AutoJSContext(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
   106   // We need this Init() method because we can't use delegating constructor for
   107   // the moment. It is a C++11 feature and we do not require C++11 to be
   108   // supported to be able to compile Gecko.
   109   void Init(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
   111   JSContext* mCx;
   112   Maybe<AutoCxPusher> mPusher;
   113   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   114 };
   116 /**
   117  * Use ThreadsafeAutoJSContext when you want an AutoJSContext but might be
   118  * running on a worker thread.
   119  */
   120 class MOZ_STACK_CLASS ThreadsafeAutoJSContext {
   121 public:
   122   ThreadsafeAutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
   123   operator JSContext*() const;
   125 private:
   126   JSContext* mCx; // Used on workers.  Null means mainthread.
   127   Maybe<JSAutoRequest> mRequest; // Used on workers.
   128   Maybe<AutoJSContext> mAutoJSContext; // Used on main thread.
   129   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   130 };
   132 /**
   133  * AutoSafeJSContext is similar to AutoJSContext but will only return the safe
   134  * JS context. That means it will never call ::GetCurrentJSContext().
   135  */
   136 class MOZ_STACK_CLASS AutoSafeJSContext : public AutoJSContext {
   137 public:
   138   AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
   139 private:
   140   JSAutoCompartment mAc;
   141 };
   143 /**
   144  * Like AutoSafeJSContext but can be used safely on worker threads.
   145  */
   146 class MOZ_STACK_CLASS ThreadsafeAutoSafeJSContext {
   147 public:
   148   ThreadsafeAutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
   149   operator JSContext*() const;
   151 private:
   152   JSContext* mCx; // Used on workers.  Null means mainthread.
   153   Maybe<JSAutoRequest> mRequest; // Used on workers.
   154   Maybe<AutoSafeJSContext> mAutoSafeJSContext; // Used on main thread.
   155   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   156 };
   158 /**
   159  * Use AutoPushJSContext when you want to use a specific JSContext that may or
   160  * may not be already on the stack. This differs from nsCxPusher in that it only
   161  * pushes in the case that the given cx is not the active cx on the JSContext
   162  * stack, which avoids an expensive JS_SaveFrameChain in the common case.
   163  *
   164  * Most consumers of this should probably just use AutoJSContext. But the goal
   165  * here is to preserve the existing behavior while ensure proper cx-stack
   166  * semantics in edge cases where the context being used doesn't match the active
   167  * context.
   168  *
   169  * NB: This will not push a null cx even if aCx is null. Make sure you know what
   170  * you're doing.
   171  */
   172 class MOZ_STACK_CLASS AutoPushJSContext {
   173   Maybe<AutoCxPusher> mPusher;
   174   JSContext* mCx;
   176 public:
   177   AutoPushJSContext(JSContext* aCx);
   178   operator JSContext*() { return mCx; }
   179 };
   181 } // namespace mozilla
   183 #endif /* nsCxPusher_h */

mercurial