/*
 * Copyright (C) 2012-2021 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 "PutByStatus.h"

#include "BytecodeStructs.h"
#include "CacheableIdentifierInlines.h"
#include "CodeBlock.h"
#include "ComplexGetStatus.h"
#include "GetterSetterAccessCase.h"
#include "ICStatusUtils.h"
#include "PolymorphicAccess.h"
#include "StructureInlines.h"
#include "StructureStubInfo.h"
#include <wtf/ListDump.h>

namespace JSC {

bool PutByStatus::appendVariant(const PutByVariant& variant)
{
    return appendICStatusVariant(m_variants, variant);
}

void PutByStatus::shrinkToFit()
{
    m_variants.shrinkToFit();
}

PutByStatus PutByStatus::computeFromLLInt(CodeBlock* profiledBlock, BytecodeIndex bytecodeIndex)
{
    VM& vm = profiledBlock->vm();
    
    auto instruction = profiledBlock->instructions().at(bytecodeIndex.offset());

    switch (instruction->opcodeID()) {
    case op_put_by_id:
        break;
    case op_put_by_val:
    case op_put_by_val_direct:
        return PutByStatus(NoInformation);
    case op_put_private_name:
        // We do no have a code retrieving LLInt information for `op_put_private_name`.
        // We can add support for it if this is required in future changes, since we have
        // IC implemented for this operation on LLInt.
        return PutByStatus(NoInformation);
    default: {
        RELEASE_ASSERT_NOT_REACHED();
        break;
    }
    }

    auto bytecode = instruction->as<OpPutById>();
    auto& metadata = bytecode.metadata(profiledBlock);
    const Identifier* identifier = &(profiledBlock->identifier(bytecode.m_property));
    UniquedStringImpl* uid = identifier->impl();

    StructureID structureID = metadata.m_oldStructureID;
    if (!structureID)
        return PutByStatus(NoInformation);
    
    Structure* structure = structureID.decode();

    StructureID newStructureID = metadata.m_newStructureID;
    if (!newStructureID) {
        PropertyOffset offset = structure->getConcurrently(uid);
        if (!isValidOffset(offset))
            return PutByStatus(NoInformation);
        
        return PutByVariant::replace(nullptr, structure, offset);
    }

    Structure* newStructure = newStructureID.decode();
    
    ASSERT(structure->transitionWatchpointSetHasBeenInvalidated());
    
    PropertyOffset offset = newStructure->getConcurrently(uid);
    if (!isValidOffset(offset))
        return PutByStatus(NoInformation);
    
    ObjectPropertyConditionSet conditionSet;
    if (!(bytecode.m_flags.isDirect())) {
        conditionSet =
            generateConditionsForPropertySetterMissConcurrently(
                vm, profiledBlock->globalObject(), structure, uid);
        if (!conditionSet.isValid())
            return PutByStatus(NoInformation);
    }
    
    return PutByVariant::transition(nullptr, structure, newStructure, conditionSet, offset);
}

#if ENABLE(JIT)
PutByStatus::PutByStatus(StubInfoSummary summary, StructureStubInfo& stubInfo)
{
    switch (summary) {
    case StubInfoSummary::NoInformation:
        m_state = NoInformation;
        return;
    case StubInfoSummary::Simple:
    case StubInfoSummary::MakesCalls:
        RELEASE_ASSERT_NOT_REACHED();
        return;
    case StubInfoSummary::TakesSlowPath:
        m_state = stubInfo.tookSlowPath ? ObservedTakesSlowPath : LikelyTakesSlowPath;
        return;
    case StubInfoSummary::TakesSlowPathAndMakesCalls:
        m_state = stubInfo.tookSlowPath ? ObservedSlowPathAndMakesCalls : MakesCalls;
        return;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

PutByStatus PutByStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, ExitFlag didExit, CallLinkStatus::ExitSiteData callExitSiteData)
{
    ConcurrentJSLocker locker(profiledBlock->m_lock);
    
    UNUSED_PARAM(profiledBlock);
    UNUSED_PARAM(bytecodeIndex);
#if ENABLE(DFG_JIT)
    if (didExit)
        return PutByStatus(LikelyTakesSlowPath);
    
    StructureStubInfo* stubInfo = map.get(CodeOrigin(bytecodeIndex)).stubInfo;
    PutByStatus result = computeForStubInfo(
        locker, profiledBlock, stubInfo, callExitSiteData);
    if (!result)
        return computeFromLLInt(profiledBlock, bytecodeIndex);
    
    return result;
#else // ENABLE(JIT)
    UNUSED_PARAM(map);
    UNUSED_PARAM(didExit);
    UNUSED_PARAM(callExitSiteData);
    return PutByStatus(NoInformation);
#endif // ENABLE(JIT)
}

PutByStatus PutByStatus::computeForStubInfo(const ConcurrentJSLocker& locker, CodeBlock* baselineBlock, StructureStubInfo* stubInfo, CodeOrigin codeOrigin)
{
    return computeForStubInfo(
        locker, baselineBlock, stubInfo,
        CallLinkStatus::computeExitSiteData(baselineBlock, codeOrigin.bytecodeIndex()));
}

PutByStatus PutByStatus::computeForStubInfo(const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CallLinkStatus::ExitSiteData callExitSiteData)
{
    StubInfoSummary summary = StructureStubInfo::summary(profiledBlock->vm(), stubInfo);
    if (!isInlineable(summary))
        return PutByStatus(summary, *stubInfo);
    
    switch (stubInfo->cacheType()) {
    case CacheType::Unset:
        // This means that we attempted to cache but failed for some reason.
        return PutByStatus(JSC::slowVersion(summary), *stubInfo);
        
    case CacheType::PutByIdReplace: {
        CacheableIdentifier identifier = stubInfo->identifier();
        UniquedStringImpl* uid = identifier.uid();
        RELEASE_ASSERT(uid);
        Structure* structure = stubInfo->inlineAccessBaseStructure();
        PropertyOffset offset = structure->getConcurrently(uid);
        if (isValidOffset(offset))
            return PutByVariant::replace(WTFMove(identifier), structure, offset);
        return PutByStatus(JSC::slowVersion(summary), *stubInfo);
    }
        
    case CacheType::Stub: {
        PolymorphicAccess* list = stubInfo->m_stub.get();

        PutByStatus result;
        result.m_state = Simple;
        
        for (unsigned i = 0; i < list->size(); ++i) {
            const AccessCase& access = list->at(i);
            if (access.viaProxy())
                return PutByStatus(JSC::slowVersion(summary), *stubInfo);
            if (access.usesPolyProto())
                return PutByStatus(JSC::slowVersion(summary), *stubInfo);
            
            switch (access.type()) {
            case AccessCase::Replace: {
                Structure* structure = access.structure();
                PropertyOffset offset = structure->getConcurrently(access.uid());
                if (!isValidOffset(offset))
                    return PutByStatus(JSC::slowVersion(summary), *stubInfo);
                auto variant = PutByVariant::replace(access.identifier(), structure, offset);
                if (!result.appendVariant(variant))
                    return PutByStatus(JSC::slowVersion(summary), *stubInfo);
                break;
            }
                
            case AccessCase::Transition: {
                PropertyOffset offset = access.newStructure()->getConcurrently(access.uid());
                if (!isValidOffset(offset))
                    return PutByStatus(JSC::slowVersion(summary), *stubInfo);
                ObjectPropertyConditionSet conditionSet = access.conditionSet();
                if (!conditionSet.structuresEnsureValidity())
                    return PutByStatus(JSC::slowVersion(summary), *stubInfo);
                auto variant = PutByVariant::transition(access.identifier(), access.structure(), access.newStructure(), conditionSet, offset);
                if (!result.appendVariant(variant))
                    return PutByStatus(JSC::slowVersion(summary), *stubInfo);
                break;
            }
                
            case AccessCase::Setter: {
                Structure* structure = access.structure();
                
                ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(structure, access.conditionSet(), access.uid());
                
                switch (complexGetStatus.kind()) {
                case ComplexGetStatus::ShouldSkip:
                    continue;
                    
                case ComplexGetStatus::TakesSlowPath:
                    return PutByStatus(JSC::slowVersion(summary), *stubInfo);
                    
                case ComplexGetStatus::Inlineable: {
                    std::unique_ptr<CallLinkStatus> callLinkStatus =
                        makeUnique<CallLinkStatus>();
                    if (CallLinkInfo* callLinkInfo = access.as<GetterSetterAccessCase>().callLinkInfo()) {
                        *callLinkStatus = CallLinkStatus::computeFor(
                            locker, profiledBlock, *callLinkInfo, callExitSiteData);
                    }
                    
                    auto variant = PutByVariant::setter(access.identifier(), structure, complexGetStatus.offset(), complexGetStatus.conditionSet(), WTFMove(callLinkStatus));
                    if (!result.appendVariant(variant))
                        return PutByStatus(JSC::slowVersion(summary), *stubInfo);
                }
                }
                break;
            }
                
            case AccessCase::CustomValueSetter:
            case AccessCase::CustomAccessorSetter:
                return PutByStatus(MakesCalls);

            default:
                return PutByStatus(JSC::slowVersion(summary), *stubInfo);
            }
        }
        
        result.shrinkToFit();
        return result;
    }
        
    default:
        return PutByStatus(JSC::slowVersion(summary), *stubInfo);
    }
}

PutByStatus PutByStatus::computeFor(CodeBlock* baselineBlock, ICStatusMap& baselineMap, ICStatusContextStack& contextStack, CodeOrigin codeOrigin)
{
    BytecodeIndex bytecodeIndex = codeOrigin.bytecodeIndex();
    CallLinkStatus::ExitSiteData callExitSiteData = CallLinkStatus::computeExitSiteData(baselineBlock, bytecodeIndex);
    ExitFlag didExit = hasBadCacheExitSite(baselineBlock, bytecodeIndex);

    for (ICStatusContext* context : contextStack) {
        ICStatus status = context->get(codeOrigin);
        
        auto bless = [&] (const PutByStatus& result) -> PutByStatus {
            if (!context->isInlined(codeOrigin)) {
                PutByStatus baselineResult = computeFor(
                    baselineBlock, baselineMap, bytecodeIndex, didExit,
                    callExitSiteData);
                baselineResult.merge(result);
                return baselineResult;
            }
            if (didExit.isSet(ExitFromInlined))
                return result.slowVersion();
            return result;
        };
        
        if (status.stubInfo) {
            PutByStatus result;
            {
                ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock);
                result = computeForStubInfo(
                    locker, context->optimizedCodeBlock, status.stubInfo, callExitSiteData);
            }
            if (result.isSet())
                return bless(result);
        }
        
        if (status.putStatus)
            return bless(*status.putStatus);
    }
    
    return computeFor(baselineBlock, baselineMap, bytecodeIndex, didExit, callExitSiteData);
}

PutByStatus PutByStatus::computeFor(JSGlobalObject* globalObject, const StructureSet& set, CacheableIdentifier identifier, bool isDirect, PrivateFieldPutKind privateFieldPutKind)
{
    UniquedStringImpl* uid = identifier.uid();
    if (parseIndex(*uid))
        return PutByStatus(LikelyTakesSlowPath);

    if (set.isEmpty())
        return PutByStatus();
    
    VM& vm = globalObject->vm();
    PutByStatus result;
    result.m_state = Simple;
    for (unsigned i = 0; i < set.size(); ++i) {
        Structure* structure = set[i];
        
        if (structure->typeInfo().overridesGetOwnPropertySlot() && structure->typeInfo().type() != GlobalObjectType)
            return PutByStatus(LikelyTakesSlowPath);

        if (!structure->propertyAccessesAreCacheable())
            return PutByStatus(LikelyTakesSlowPath);
    
        unsigned attributes;
        PropertyOffset offset = structure->getConcurrently(uid, attributes);
        if (isValidOffset(offset)) {
            // We can't have a valid offset for structures on `PutPrivateNameById` define mode
            // since it means we are redefining a private field. In such case, we need to take 
            // slow path to throw exception.
            if (privateFieldPutKind.isDefine())
                return PutByStatus(LikelyTakesSlowPath);

            if (attributes & PropertyAttribute::CustomAccessorOrValue)
                return PutByStatus(MakesCalls);

            if (attributes & (PropertyAttribute::Accessor | PropertyAttribute::ReadOnly))
                return PutByStatus(LikelyTakesSlowPath);
            
            WatchpointSet* replaceSet = structure->propertyReplacementWatchpointSet(offset);
            if (!replaceSet || replaceSet->isStillValid()) {
                // When this executes, it'll create, and fire, this replacement watchpoint set.
                // That means that  this has probably never executed or that something fishy is
                // going on. Also, we cannot create or fire the watchpoint set from the concurrent
                // JIT thread, so even if we wanted to do this, we'd need to have a lazy thingy.
                // So, better leave this alone and take slow path.
                return PutByStatus(LikelyTakesSlowPath);
            }

            PutByVariant variant = PutByVariant::replace(identifier, structure, offset);
            if (!result.appendVariant(variant))
                return PutByStatus(LikelyTakesSlowPath);
            continue;
        }

        // We can have a case with PutPrivateNameById in set mode and it
        // should never cause a structure transition because it means we are
        // trying to store in a not installed private field. We need to take
        // slow path to throw excpetion if it ever gets executed.
        if (privateFieldPutKind.isSet())
            return PutByStatus(LikelyTakesSlowPath);

        // Our hypothesis is that we're doing a transition. Before we prove that this is really
        // true, we want to do some sanity checks.
    
        // Don't cache put transitions on dictionaries.
        if (structure->isDictionary())
            return PutByStatus(LikelyTakesSlowPath);

        // If the structure corresponds to something that isn't an object, then give up, since
        // we don't want to be adding properties to strings.
        if (!structure->typeInfo().isObject())
            return PutByStatus(LikelyTakesSlowPath);
    
        ObjectPropertyConditionSet conditionSet;
        if (!isDirect) {
            ASSERT(privateFieldPutKind.isNone());
            conditionSet = generateConditionsForPropertySetterMissConcurrently(
                vm, globalObject, structure, uid);
            if (!conditionSet.isValid())
                return PutByStatus(LikelyTakesSlowPath);
        }
    
        // We only optimize if there is already a structure that the transition is cached to.
        Structure* transition =
            Structure::addPropertyTransitionToExistingStructureConcurrently(structure, uid, 0, offset);
        if (!transition)
            return PutByStatus(LikelyTakesSlowPath);
        ASSERT(isValidOffset(offset));
    
        bool didAppend = result.appendVariant(PutByVariant::transition(identifier, structure, transition, conditionSet, offset));
        if (!didAppend)
            return PutByStatus(LikelyTakesSlowPath);
    }
    
    result.shrinkToFit();
    return result;
}
#endif

bool PutByStatus::makesCalls() const
{
    switch (m_state) {
    case NoInformation:
    case LikelyTakesSlowPath:
    case ObservedTakesSlowPath:
        return false;
    case MakesCalls:
    case ObservedSlowPathAndMakesCalls:
        return true;
    case Simple: {
        for (unsigned i = m_variants.size(); i--;) {
            if (m_variants[i].makesCalls())
                return true;
        }
        return false;
    }
    default:
        RELEASE_ASSERT_NOT_REACHED();
    }
}

PutByStatus PutByStatus::slowVersion() const
{
    if (observedStructureStubInfoSlowPath())
        return PutByStatus(makesCalls() ? ObservedSlowPathAndMakesCalls : ObservedTakesSlowPath);
    return PutByStatus(makesCalls() ? MakesCalls : LikelyTakesSlowPath);
}

CacheableIdentifier PutByStatus::singleIdentifier() const
{
    return singleIdentifierForICStatus(m_variants);
}

template<typename Visitor>
void PutByStatus::visitAggregateImpl(Visitor& visitor)
{
    for (PutByVariant& variant : m_variants)
        variant.visitAggregate(visitor);
}

DEFINE_VISIT_AGGREGATE(PutByStatus);

template<typename Visitor>
void PutByStatus::markIfCheap(Visitor& visitor)
{
    for (PutByVariant& variant : m_variants)
        variant.markIfCheap(visitor);
}

template void PutByStatus::markIfCheap(AbstractSlotVisitor&);
template void PutByStatus::markIfCheap(SlotVisitor&);

bool PutByStatus::finalize(VM& vm)
{
    for (PutByVariant& variant : m_variants) {
        if (!variant.finalize(vm))
            return false;
    }
    return true;
}

void PutByStatus::merge(const PutByStatus& other)
{
    if (other.m_state == NoInformation)
        return;

    auto mergeSlow = [&] () {
        if (observedStructureStubInfoSlowPath() || other.observedStructureStubInfoSlowPath())
            *this = PutByStatus((makesCalls() || other.makesCalls()) ? ObservedSlowPathAndMakesCalls : ObservedTakesSlowPath);
        else
            *this = PutByStatus((makesCalls() || other.makesCalls()) ? MakesCalls : LikelyTakesSlowPath);
    };

    switch (m_state) {
    case NoInformation:
        *this = other;
        return;
        
    case Simple:
        if (other.m_state != Simple)
            return mergeSlow();
        
        for (const PutByVariant& other : other.m_variants) {
            if (!appendVariant(other))
                return mergeSlow();
        }
        shrinkToFit();
        return;
        
    case LikelyTakesSlowPath:
    case ObservedTakesSlowPath:
    case MakesCalls:
    case ObservedSlowPathAndMakesCalls:
        return mergeSlow();
    }
    
    RELEASE_ASSERT_NOT_REACHED();
}

void PutByStatus::filter(const StructureSet& set)
{
    if (m_state != Simple)
        return;
    filterICStatusVariants(m_variants, set);
    for (PutByVariant& variant : m_variants)
        variant.fixTransitionToReplaceIfNecessary();
    if (m_variants.isEmpty())
        m_state = NoInformation;
}

void PutByStatus::dump(PrintStream& out) const
{
    switch (m_state) {
    case NoInformation:
        out.print("(NoInformation)");
        return;
    case Simple:
        out.print("(", listDump(m_variants), ")");
        return;
    case LikelyTakesSlowPath:
        out.print("LikelyTakesSlowPath");
        return;
    case ObservedTakesSlowPath:
        out.print("ObservedTakesSlowPath");
        return;
    case MakesCalls:
        out.print("MakesCalls");
        return;
    case ObservedSlowPathAndMakesCalls:
        out.print("ObservedSlowPathAndMakesCalls");
        return;
    }
    
    RELEASE_ASSERT_NOT_REACHED();
}

} // namespace JSC

