#ifndef StackBounds_h
#define StackBounds_h
namespace WTF {
class StackBounds {
const static size_t s_defaultAvailabilityDelta = 4096;
public:
StackBounds()
: m_origin(0)
, m_bound(0)
{
}
static StackBounds currentThreadStackBounds()
{
StackBounds bounds;
bounds.initialize();
bounds.checkConsistency();
return bounds;
}
void* origin() const
{
ASSERT(m_origin);
return m_origin;
}
void* current() const
{
checkConsistency();
void* currentPosition = ¤tPosition;
return currentPosition;
}
void* recursionLimit(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
{
checkConsistency();
return isGrowingDownward()
? static_cast<char*>(m_bound) + minAvailableDelta
: static_cast<char*>(m_bound) - minAvailableDelta;
}
bool recursionCheck(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
{
checkConsistency();
return isGrowingDownward()
? current() >= recursionLimit(minAvailableDelta)
: current() <= recursionLimit(minAvailableDelta);
}
private:
void initialize();
bool isGrowingDownward() const
{
ASSERT(m_origin && m_bound);
#if OS(WINCE)
return m_origin > m_bound;
#else
return true;
#endif
}
void checkConsistency() const
{
#if !ASSERT_DISABLED
void* currentPosition = ¤tPosition;
ASSERT(m_origin != m_bound);
ASSERT(isGrowingDownward()
? (currentPosition < m_origin && currentPosition > m_bound)
: (currentPosition > m_origin && currentPosition < m_bound));
#endif
}
void* m_origin;
void* m_bound;
};
}
using WTF::StackBounds;
#endif