/*
 * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "PropertyCondition.h"

#include "GetterSetter.h"
#include "JSCInlines.h"
#include "TrackedReferences.h"

namespace JSC {

namespace PropertyConditionInternal {
static bool verbose = false;
}

void PropertyCondition::dumpInContext(PrintStream& out, DumpContext* context) const
{
    if (!*this) {
        out.print("<invalid>");
        return;
    }
    
    switch (m_header.type()) {
    case Presence:
        out.print(m_header.type(), " of ", m_header.pointer(), " at ", offset(), " with attributes ", attributes());
        return;
    case Absence:
    case AbsenceOfSetEffect:
        out.print(m_header.type(), " of ", m_header.pointer(), " with prototype ", inContext(JSValue(prototype()), context));
        return;
    case Equivalence:
        out.print(m_header.type(), " of ", m_header.pointer(), " with ", inContext(requiredValue(), context));
        return;
    case HasStaticProperty:
        out.print(m_header.type(), " of ", m_header.pointer());
        return;
    case HasPrototype:
        out.print(m_header.type(), " with prototype ", inContext(JSValue(prototype()), context));
        return;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

void PropertyCondition::dump(PrintStream& out) const
{
    dumpInContext(out, nullptr);
}

ALWAYS_INLINE static bool nonStructurePropertyMayBecomeReadOnlyWithoutTransition(Structure* structure, UniquedStringImpl* uid)
{
    switch (structure->typeInfo().type()) {
    case ArrayType:
    case DerivedArrayType:
        return uid == structure->vm().propertyNames->length.impl();

    case RegExpObjectType:
        return uid == structure->vm().propertyNames->lastIndex.impl();

    default:
        return false;
    }
}

bool PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint(
    Concurrency concurrency, Structure* structure, JSObject* base) const
{
    if (PropertyConditionInternal::verbose) {
        dataLog(
            "Determining validity of ", *this, " with structure ", pointerDump(structure), " and base ",
            JSValue(base), " assuming impure property watchpoints are set.\n");
    }
    
    if (!*this) {
        if (PropertyConditionInternal::verbose)
            dataLog("Invalid because unset.\n");
        return false;
    }

    switch (m_header.type()) {
    case Presence:
    case Absence:
    case AbsenceOfSetEffect:
    case Equivalence:
    case HasStaticProperty:
        if (!structure->propertyAccessesAreCacheable()) {
            if (PropertyConditionInternal::verbose)
                dataLog("Invalid because property accesses are not cacheable.\n");
            return false;
        }
        break;
        
    case HasPrototype:
        if (!structure->prototypeQueriesAreCacheable()) {
            if (PropertyConditionInternal::verbose)
                dataLog("Invalid because prototype queries are not cacheable.\n");
            return false;
        }
        break;
    }
    
    switch (m_header.type()) {
    case Presence: {
        unsigned currentAttributes;
        PropertyOffset currentOffset = structure->get(structure->vm(), concurrency, uid(), currentAttributes);
        if (currentOffset != offset() || currentAttributes != attributes()) {
            if (PropertyConditionInternal::verbose) {
                dataLog(
                    "Invalid because we need offset, attributes to be ", offset(), ", ", attributes(),
                    " but they are ", currentOffset, ", ", currentAttributes, "\n");
            }
            return false;
        }
        return true;
    }
        
    case Absence: {
        if (structure->isDictionary()) {
            if (PropertyConditionInternal::verbose)
                dataLog("Invalid because it's a dictionary.\n");
            return false;
        }

        if (structure->hasPolyProto()) {
            // FIXME: I think this is too conservative. We can probably prove this if
            // we have the base. Anyways, we should make this work when integrating
            // OPC and poly proto.
            // https://bugs.webkit.org/show_bug.cgi?id=177339
            return false;
        }

        PropertyOffset currentOffset = structure->get(structure->vm(), concurrency, uid());
        if (currentOffset != invalidOffset) {
            if (PropertyConditionInternal::verbose)
                dataLog("Invalid because the property exists at offset: ", currentOffset, "\n");
            return false;
        }

        if (structure->storedPrototypeObject() != prototype()) {
            if (PropertyConditionInternal::verbose) {
                dataLog(
                    "Invalid because the prototype is ", structure->storedPrototype(), " even though "
                    "it should have been ", JSValue(prototype()), "\n");
            }
            return false;
        }
        
        return true;
    }
    
    case AbsenceOfSetEffect: {
        if (structure->isDictionary()) {
            if (PropertyConditionInternal::verbose)
                dataLog("Invalid because it's a dictionary.\n");
            return false;
        }
        
        unsigned currentAttributes;
        PropertyOffset currentOffset = structure->get(structure->vm(), concurrency, uid(), currentAttributes);
        if (currentOffset != invalidOffset) {
            if (currentAttributes & (PropertyAttribute::ReadOnly | PropertyAttribute::Accessor | PropertyAttribute::CustomAccessorOrValue)) {
                if (PropertyConditionInternal::verbose) {
                    dataLog(
                        "Invalid because we expected not to have a setter, but we have one at offset ",
                        currentOffset, " with attributes ", currentAttributes, "\n");
                }
                return false;
            }
        } else if (nonStructurePropertyMayBecomeReadOnlyWithoutTransition(structure, uid())) {
            if (PropertyConditionInternal::verbose)
                dataLog("Invalid because its put() override may treat ", uid(), " property as read-only.\n");
            return false;
        }

        if (structure->hasPolyProto()) {
            // FIXME: I think this is too conservative. We can probably prove this if
            // we have the base. Anyways, we should make this work when integrating
            // OPC and poly proto.
            // https://bugs.webkit.org/show_bug.cgi?id=177339
            return false;
        }
        
        if (structure->storedPrototypeObject() != prototype()) {
            if (PropertyConditionInternal::verbose) {
                dataLog(
                    "Invalid because the prototype is ", structure->storedPrototype(), " even though "
                    "it should have been ", JSValue(prototype()), "\n");
            }
            return false;
        }
        
        return true;
    }
        
    case HasPrototype: {
        if (structure->hasPolyProto()) {
            // FIXME: I think this is too conservative. We can probably prove this if
            // we have the base. Anyways, we should make this work when integrating
            // OPC and poly proto.
            // https://bugs.webkit.org/show_bug.cgi?id=177339
            return false;
        }

        if (structure->storedPrototypeObject() != prototype()) {
            if (PropertyConditionInternal::verbose) {
                dataLog(
                    "Invalid because the prototype is ", structure->storedPrototype(), " even though "
                    "it should have been ", JSValue(prototype()), "\n");
            }
            return false;
        }
        
        return true;
    }
        
    case Equivalence: {
        if (!base || base->structure() != structure) {
            // Conservatively return false, since we cannot verify this one without having the
            // object.
            if (PropertyConditionInternal::verbose) {
                dataLog(
                    "Invalid because we don't have a base or the base has the wrong structure: ",
                    RawPointer(base), "\n");
            }
            return false;
        }
        
        // FIXME: This is somewhat racy, and maybe more risky than we want.
        // https://bugs.webkit.org/show_bug.cgi?id=134641
        
        PropertyOffset currentOffset = structure->get(structure->vm(), concurrency, uid());
        if (currentOffset == invalidOffset) {
            if (PropertyConditionInternal::verbose) {
                dataLog(
                    "Invalid because the base no long appears to have ", uid(), " on its structure: ",
                        RawPointer(base), "\n");
            }
            return false;
        }

        JSValue currentValue = base->getDirect(concurrency, structure, currentOffset);
        if (currentValue != requiredValue()) {
            if (PropertyConditionInternal::verbose) {
                dataLog(
                    "Invalid because the value is ", currentValue, " but we require ", requiredValue(),
                    "\n");
            }
            return false;
        }
        
        return true;
    } 
    case HasStaticProperty: {
        if (isValidOffset(structure->get(structure->vm(), concurrency, uid())))
            return false;
        if (structure->staticPropertiesReified())
            return false;
        return !!structure->findPropertyHashEntry(uid());
    }
    }
    
    RELEASE_ASSERT_NOT_REACHED();
}

IGNORE_RETURN_TYPE_WARNINGS_BEGIN
static ALWAYS_INLINE Concurrency watchabilityToConcurrency(PropertyCondition::WatchabilityEffort effort)
{
    switch (effort) {
    case PropertyCondition::WatchabilityEffort::EnsureWatchability:
        return Concurrency::MainThread;
    case PropertyCondition::WatchabilityEffort::MakeNoChanges:
        return Concurrency::ConcurrentThread;
    }
}
IGNORE_RETURN_TYPE_WARNINGS_END

bool PropertyCondition::validityRequiresImpurePropertyWatchpoint(Structure* structure) const
{
    if (!*this)
        return false;
    
    switch (m_header.type()) {
    case Presence:
    case Absence:
    case Equivalence:
    case HasStaticProperty:
        return structure->needImpurePropertyWatchpoint();
    case AbsenceOfSetEffect:
    case HasPrototype:
        return false;
    }
    
    RELEASE_ASSERT_NOT_REACHED();
}

bool PropertyCondition::isStillValid(Concurrency concurrency, Structure* structure, JSObject* base) const
{
    if (!isStillValidAssumingImpurePropertyWatchpoint(concurrency, structure, base))
        return false;

    // Currently we assume that an impure property can cause a property to appear, and can also
    // "shadow" an existing JS property on the same object. Hence it affects both presence and
    // absence. It doesn't affect AbsenceOfSetEffect because impure properties aren't ever setters.
    switch (m_header.type()) {
    case Absence:
        if (structure->typeInfo().getOwnPropertySlotIsImpure() || structure->typeInfo().getOwnPropertySlotIsImpureForPropertyAbsence())
            return false;
        break;
    case Presence:
    case Equivalence:
    case HasStaticProperty:
        if (structure->typeInfo().getOwnPropertySlotIsImpure())
            return false;
        break;
    default:
        break;
    }
    
    return true;
}

bool PropertyCondition::isWatchableWhenValid(
    Structure* structure, WatchabilityEffort effort) const
{
    if (structure->transitionWatchpointSetHasBeenInvalidated())
        return false;
    
    switch (m_header.type()) {
    case Equivalence: {
        PropertyOffset offset = structure->get(structure->vm(), watchabilityToConcurrency(effort), uid());
        
        // This method should only be called when some variant of isValid returned true, which
        // implies that we already confirmed that the structure knows of the property. We should
        // also have verified that the Structure is a cacheable dictionary, which means we
        // shouldn't have a TOCTOU race either.
        RELEASE_ASSERT(offset != invalidOffset);
        
        WatchpointSet* set = nullptr;
        switch (effort) {
        case MakeNoChanges:
            set = structure->propertyReplacementWatchpointSet(offset);
            break;
        case EnsureWatchability:
            set = structure->ensurePropertyReplacementWatchpointSet(structure->vm(), offset);
            break;
        }
        
        if (!set || !set->isStillValid())
            return false;
        
        break;
    }

    case HasStaticProperty: {
        // We just use the structure transition watchpoint for this. A structure S starts
        // off with a property P in the static property hash table. If S transitions to
        // S', either P remains in the static property table or not. If not, then we
        // are no longer valid. So the above check of transitionWatchpointSetHasBeenInvalidated
        // is sufficient.
        //
        // We could make this smarter in the future, since we sometimes reify static properties.
        // We could make this adapt to looking at the object's storage for such reified custom
        // functions, but we don't do that right now. We just allow this property condition to
        // invalidate and create an Equivalence watchpoint for the materialized property sometime
        // in the future.
        break;
    }
        
    default:
        break;
    }
    
    return true;
}

bool PropertyCondition::isWatchableAssumingImpurePropertyWatchpoint(
    Structure* structure, JSObject* base, WatchabilityEffort effort) const
{
    return isStillValidAssumingImpurePropertyWatchpoint(watchabilityToConcurrency(effort), structure, base)
        && isWatchableWhenValid(structure, effort);
}

bool PropertyCondition::isWatchable(
    Structure* structure, JSObject* base, WatchabilityEffort effort) const
{
    return isStillValid(watchabilityToConcurrency(effort), structure, base)
        && isWatchableWhenValid(structure, effort);
}

void PropertyCondition::validateReferences(const TrackedReferences& tracked) const
{
    if (hasPrototype())
        tracked.check(prototype());
    
    if (hasRequiredValue())
        tracked.check(requiredValue());
}

bool PropertyCondition::isValidValueForAttributes(JSValue value, unsigned attributes)
{
    if (!value)
        return false;
    bool attributesClaimAccessor = !!(attributes & PropertyAttribute::Accessor);
    bool valueClaimsAccessor = !!jsDynamicCast<GetterSetter*>(value);
    return attributesClaimAccessor == valueClaimsAccessor;
}

bool PropertyCondition::isValidValueForPresence(JSValue value) const
{
    return isValidValueForAttributes(value, attributes());
}

PropertyCondition PropertyCondition::attemptToMakeEquivalenceWithoutBarrier(JSObject* base) const
{
    Structure* structure = base->structure();

    JSValue value = base->getDirectConcurrently(structure, offset());
    if (!isValidValueForPresence(value))
        return PropertyCondition();
    return equivalenceWithoutBarrier(uid(), value);
}

} // namespace JSC

namespace WTF {

void printInternal(PrintStream& out, JSC::PropertyCondition::Kind condition)
{
    switch (condition) {
    case JSC::PropertyCondition::Presence:
        out.print("Presence");
        return;
    case JSC::PropertyCondition::Absence:
        out.print("Absence");
        return;
    case JSC::PropertyCondition::AbsenceOfSetEffect:
        out.print("Absence");
        return;
    case JSC::PropertyCondition::Equivalence:
        out.print("Equivalence");
        return;
    case JSC::PropertyCondition::HasStaticProperty:
        out.print("HasStaticProperty");
        return;
    case JSC::PropertyCondition::HasPrototype:
        out.print("HasPrototype");
        return;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

} // namespace WTF
