ObjectPropertyCondition.h [plain text]
#pragma once
#include "JSObject.h"
#include "PropertyCondition.h"
#include <wtf/HashMap.h>
namespace JSC {
class TrackedReferences;
class ObjectPropertyCondition {
public:
ObjectPropertyCondition()
: m_object(nullptr)
{
}
ObjectPropertyCondition(WTF::HashTableDeletedValueType token)
: m_object(nullptr)
, m_condition(token)
{
}
ObjectPropertyCondition(JSObject* object, const PropertyCondition& condition)
: m_object(object)
, m_condition(condition)
{
}
static ObjectPropertyCondition presenceWithoutBarrier(
JSObject* object, UniquedStringImpl* uid, PropertyOffset offset, unsigned attributes)
{
ObjectPropertyCondition result;
result.m_object = object;
result.m_condition = PropertyCondition::presenceWithoutBarrier(uid, offset, attributes);
return result;
}
static ObjectPropertyCondition presence(
VM& vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid, PropertyOffset offset,
unsigned attributes)
{
if (owner)
vm.heap.writeBarrier(owner);
return presenceWithoutBarrier(object, uid, offset, attributes);
}
static ObjectPropertyCondition absenceWithoutBarrier(
JSObject* object, UniquedStringImpl* uid, JSObject* prototype)
{
ObjectPropertyCondition result;
result.m_object = object;
result.m_condition = PropertyCondition::absenceWithoutBarrier(uid, prototype);
return result;
}
static ObjectPropertyCondition absence(
VM& vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid, JSObject* prototype)
{
if (owner)
vm.heap.writeBarrier(owner);
return absenceWithoutBarrier(object, uid, prototype);
}
static ObjectPropertyCondition absenceOfSetEffectWithoutBarrier(
JSObject* object, UniquedStringImpl* uid, JSObject* prototype)
{
ObjectPropertyCondition result;
result.m_object = object;
result.m_condition = PropertyCondition::absenceOfSetEffectWithoutBarrier(uid, prototype);
return result;
}
static ObjectPropertyCondition absenceOfSetEffect(
VM& vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid, JSObject* prototype)
{
if (owner)
vm.heap.writeBarrier(owner);
return absenceOfSetEffectWithoutBarrier(object, uid, prototype);
}
static ObjectPropertyCondition equivalenceWithoutBarrier(
JSObject* object, UniquedStringImpl* uid, JSValue value)
{
ObjectPropertyCondition result;
result.m_object = object;
result.m_condition = PropertyCondition::equivalenceWithoutBarrier(uid, value);
return result;
}
static ObjectPropertyCondition equivalence(
VM& vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid, JSValue value)
{
if (owner)
vm.heap.writeBarrier(owner);
return equivalenceWithoutBarrier(object, uid, value);
}
static ObjectPropertyCondition hasStaticProperty(
VM& vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid)
{
ObjectPropertyCondition result;
result.m_object = object;
result.m_condition = PropertyCondition::hasStaticProperty(uid);
if (owner)
vm.heap.writeBarrier(owner);
return result;
}
static ObjectPropertyCondition hasPrototypeWithoutBarrier(JSObject* object, JSObject* prototype)
{
ObjectPropertyCondition result;
result.m_object = object;
result.m_condition = PropertyCondition::hasPrototypeWithoutBarrier(prototype);
return result;
}
static ObjectPropertyCondition hasPrototype(
VM& vm, JSCell* owner, JSObject* object, JSObject* prototype)
{
if (owner)
vm.heap.writeBarrier(owner);
return hasPrototypeWithoutBarrier(object, prototype);
}
explicit operator bool() const { return !!m_condition; }
JSObject* object() const { return m_object; }
PropertyCondition condition() const { return m_condition; }
PropertyCondition::Kind kind() const { return condition().kind(); }
UniquedStringImpl* uid() const { return condition().uid(); }
bool hasOffset() const { return condition().hasOffset(); }
PropertyOffset offset() const { return condition().offset(); }
unsigned hasAttributes() const { return condition().hasAttributes(); }
unsigned attributes() const { return condition().attributes(); }
bool hasPrototype() const { return condition().hasPrototype(); }
JSObject* prototype() const { return condition().prototype(); }
bool hasRequiredValue() const { return condition().hasRequiredValue(); }
JSValue requiredValue() const { return condition().requiredValue(); }
void dumpInContext(PrintStream&, DumpContext*) const;
void dump(PrintStream&) const;
unsigned hash() const
{
return WTF::PtrHash<JSObject*>::hash(m_object) ^ m_condition.hash();
}
bool operator==(const ObjectPropertyCondition& other) const
{
return m_object == other.m_object
&& m_condition == other.m_condition;
}
bool isHashTableDeletedValue() const
{
return !m_object && m_condition.isHashTableDeletedValue();
}
bool isCompatibleWith(const ObjectPropertyCondition& other) const
{
if (!*this || !other)
return false;
return *this == other || uid() != other.uid() || object() != other.object();
}
bool structureEnsuresValidityAssumingImpurePropertyWatchpoint() const;
bool validityRequiresImpurePropertyWatchpoint(Structure*) const;
bool validityRequiresImpurePropertyWatchpoint() const;
bool isStillValidAssumingImpurePropertyWatchpoint(Structure*) const;
bool isStillValidAssumingImpurePropertyWatchpoint() const;
bool isStillValid(Structure*) const;
bool isStillValid() const;
bool structureEnsuresValidity(Structure*) const;
bool structureEnsuresValidity() const;
bool isWatchableAssumingImpurePropertyWatchpoint(
Structure*,
PropertyCondition::WatchabilityEffort = PropertyCondition::MakeNoChanges) const;
bool isWatchableAssumingImpurePropertyWatchpoint(
PropertyCondition::WatchabilityEffort = PropertyCondition::MakeNoChanges) const;
bool isWatchable(
Structure*,
PropertyCondition::WatchabilityEffort = PropertyCondition::MakeNoChanges) const;
bool isWatchable(
PropertyCondition::WatchabilityEffort = PropertyCondition::MakeNoChanges) const;
bool watchingRequiresStructureTransitionWatchpoint() const
{
return condition().watchingRequiresStructureTransitionWatchpoint();
}
bool watchingRequiresReplacementWatchpoint() const
{
return condition().watchingRequiresReplacementWatchpoint();
}
template<typename Functor>
void forEachDependentCell(const Functor& functor) const
{
functor(m_object);
m_condition.forEachDependentCell(functor);
}
bool isStillLive(VM&) const;
void validateReferences(const TrackedReferences&) const;
bool isValidValueForPresence(VM& vm, JSValue value) const
{
return condition().isValidValueForPresence(vm, value);
}
ObjectPropertyCondition attemptToMakeEquivalenceWithoutBarrier(VM&) const;
private:
JSObject* m_object;
PropertyCondition m_condition;
};
struct ObjectPropertyConditionHash {
static unsigned hash(const ObjectPropertyCondition& key) { return key.hash(); }
static bool equal(
const ObjectPropertyCondition& a, const ObjectPropertyCondition& b)
{
return a == b;
}
static constexpr bool safeToCompareToEmptyOrDeleted = true;
};
}
namespace WTF {
template<typename T> struct DefaultHash;
template<> struct DefaultHash<JSC::ObjectPropertyCondition> : JSC::ObjectPropertyConditionHash { };
template<typename T> struct HashTraits;
template<> struct HashTraits<JSC::ObjectPropertyCondition> : SimpleClassHashTraits<JSC::ObjectPropertyCondition> { };
}