/usr/include/thunderbird/nsCxPusher.h is in thunderbird-dev 1:24.4.0+build1-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
#ifndef nsCxPusher_h
#define nsCxPusher_h
#include "jsapi.h"
#include "mozilla/Util.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace dom {
class EventTarget;
}
}
class nsIScriptContext;
namespace mozilla {
/**
* Fundamental cx pushing class. All other cx pushing classes are implemented
* in terms of this class.
*/
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; }
private:
mozilla::Maybe<JSAutoRequest> mAutoRequest;
mozilla::Maybe<JSAutoCompartment> mAutoCompartment;
nsCOMPtr<nsIScriptContext> mScx;
bool mScriptIsRunning;
#ifdef DEBUG
JSContext* mPushedContext;
unsigned mCompartmentDepthOnEntry;
#endif
};
} /* namespace mozilla */
/**
* Legacy cx pushing class.
*
* This class provides a rather wonky interface, with the following quirks:
* * The constructor is a no-op, and callers must explicitly call one of
* the Push() methods.
* * Null must be pushed with PushNull().
* * The cx pusher can be reused multiple times with RePush().
*
* This class implements this interface in terms of the much simpler
* AutoCxPusher class below.
*/
class MOZ_STACK_CLASS nsCxPusher
{
public:
// This destructor doesn't actually do anything, but it implicitly depends on
// the Maybe<AutoCxPusher> destructor, which in turn depends on the
// ~AutoCxPusher destructor. If we stick with the default destructor, the
// caller needs to be able to link against the AutoCxPusher destructor, which
// isn't possible with externally-linked consumers like xpcshell. Hoist this
// work into nsCxPusher.cpp and use NS_EXPORT to make it all work right.
NS_EXPORT ~nsCxPusher();
// Returns false if something erroneous happened.
bool Push(mozilla::dom::EventTarget *aCurrentTarget);
// If nothing has been pushed to stack, this works like Push.
// Otherwise if context will change, Pop and Push will be called.
bool RePush(mozilla::dom::EventTarget *aCurrentTarget);
// If a null JSContext is passed to Push(), that will cause no
// push to happen and false to be returned.
NS_EXPORT_(void) Push(JSContext *cx);
// Explicitly push a null JSContext on the the stack
void PushNull();
// Pop() will be a no-op if Push() or PushNull() fail
NS_EXPORT_(void) Pop();
nsIScriptContext* GetCurrentScriptContext() {
return mPusher.empty() ? nullptr : mPusher.ref().GetScriptContext();
}
private:
mozilla::Maybe<mozilla::AutoCxPusher> mPusher;
};
namespace mozilla {
/**
* Use AutoJSContext when you need a JS context on the stack but don't have one
* passed as a parameter. AutoJSContext will take care of finding the most
* appropriate JS context and release it when leaving the stack.
*/
class MOZ_STACK_CLASS AutoJSContext {
public:
AutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
operator JSContext*() const;
protected:
AutoJSContext(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
private:
// We need this Init() method because we can't use delegating constructor for
// the moment. It is a C++11 feature and we do not require C++11 to be
// supported to be able to compile Gecko.
void Init(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
JSContext* mCx;
Maybe<AutoCxPusher> mPusher;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
/**
* AutoSafeJSContext is similar to AutoJSContext but will only return the safe
* JS context. That means it will never call ::GetCurrentJSContext().
*/
class MOZ_STACK_CLASS AutoSafeJSContext : public AutoJSContext {
public:
AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
};
/**
* Use AutoPushJSContext when you want to use a specific JSContext that may or
* may not be already on the stack. This differs from nsCxPusher in that it only
* pushes in the case that the given cx is not the active cx on the JSContext
* stack, which avoids an expensive JS_SaveFrameChain in the common case.
*
* Most consumers of this should probably just use AutoJSContext. But the goal
* here is to preserve the existing behavior while ensure proper cx-stack
* semantics in edge cases where the context being used doesn't match the active
* context.
*
* NB: This will not push a null cx even if aCx is null. Make sure you know what
* you're doing.
*/
class MOZ_STACK_CLASS AutoPushJSContext {
Maybe<AutoCxPusher> mPusher;
JSContext* mCx;
public:
AutoPushJSContext(JSContext* aCx);
operator JSContext*() { return mCx; }
};
} // namespace mozilla
#endif /* nsCxPusher_h */
|