FiltrationResult AbstractValue::filter(Graph& graph, const StructureSet& other)
{
    if (isClear())
        return FiltrationOK;
    
    // FIXME: This could be optimized for the common case of m_type not
    // having structures, array modes, or a specific value.
    // https://bugs.webkit.org/show_bug.cgi?id=109663
    
    m_type &= other.speculationFromStructures();
    m_arrayModes &= other.arrayModesFromStructures();
    m_currentKnownStructure.filter(other);
    
    // It's possible that prior to the above two statements we had (Foo, TOP), where
    // Foo is a SpeculatedType that is disjoint with the passed StructureSet. In that
    // case, we will now have (None, [someStructure]). In general, we need to make
    // sure that new information gleaned from the SpeculatedType needs to be fed back
    // into the information gleaned from the StructureSet.
    m_currentKnownStructure.filter(m_type);
    
    if (m_currentKnownStructure.hasSingleton())
        setFuturePossibleStructure(graph, m_currentKnownStructure.singleton());
        
    filterArrayModesByType();
    filterValueByType();
    return normalizeClarity();
}
FiltrationResult AbstractValue::changeStructure(Graph& graph, const StructureSet& other)
{
    m_type &= other.speculationFromStructures();
    m_arrayModes = other.arrayModesFromStructures();
    m_structure = other;
    
    filterValueByType();
    
    return normalizeClarity(graph);
}
void AbstractValue::set(Graph& graph, const StructureSet& set)
{
    m_structure = set;
    m_arrayModes = set.arrayModesFromStructures();
    m_type = set.speculationFromStructures();
    m_value = JSValue();
    
    checkConsistency();
    assertIsRegistered(graph);
}