/*
 * Copyright (C) 2014, 2015 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. 
 */

#ifndef ComplexGetStatus_h
#define ComplexGetStatus_h

#include "JSCJSValue.h"
#include "ObjectPropertyConditionSet.h"
#include "PropertyOffset.h"

namespace JSC {

class CodeBlock;
class StructureChain;

// This class is useful for figuring out how to inline a cached get-like access. We
// say "get-like" because this is appropriate for loading the GetterSetter object in
// a put_by_id that hits a setter. Notably, this doesn't figure out how to call
// accessors, or even whether they should be called. What it gives us, is a way of
// determining how to load the value from the requested property (identified by a
// StringImpl* uid) from an object of the given structure in the given CodeBlock,
// assuming that such an access had already been cached by Repatch (and so Repatch had
// already done a bunch of safety checks). This doesn't reexecute any checks that
// Repatch would have executed, and for prototype chain accesses, it doesn't ask the
// objects in the prototype chain whether their getOwnPropertySlot would attempt to
// intercept the access - so this really is only appropriate if you already know that
// one of the JITOperations had OK'd this for caching and that Repatch concurred.
//
// The typical use pattern is something like:
//
//     ComplexGetStatus status = ComplexGetStatus::computeFor(...);
//     switch (status.kind()) {
//     case ComplexGetStatus::ShouldSkip:
//         // Handle the case where this kind of access is possibly safe but wouldn't
//         // pass the required safety checks. For example, if an IC gives us a list of
//         // accesses and one of them is ShouldSkip, then we should pretend as if it
//         // wasn't even there.
//         break;
//     case ComplexGetStatus::TakesSlowPath:
//         // This kind of access is not safe to inline. Bail out of any attempst to
//         // inline.
//         break;
//     case ComplexGetStatus::Inlineable:
//         // The good stuff goes here. If it's Inlineable then the other properties of
//         // the 'status' object will tell you everything you need to know about how
//         // to execute the get-like operation.
//         break;
//     }

class ComplexGetStatus {
public:
    enum Kind {
        ShouldSkip,
        TakesSlowPath,
        Inlineable
    };
    
    ComplexGetStatus()
        : m_kind(ShouldSkip)
        , m_offset(invalidOffset)
    {
    }
    
    static ComplexGetStatus skip()
    {
        return ComplexGetStatus();
    }
    
    static ComplexGetStatus takesSlowPath()
    {
        ComplexGetStatus result;
        result.m_kind = TakesSlowPath;
        return result;
    }
    
    static ComplexGetStatus computeFor(
        Structure* headStructure, const ObjectPropertyConditionSet&, UniquedStringImpl* uid);
    
    Kind kind() const { return m_kind; }
    PropertyOffset offset() const { return m_offset; }
    const ObjectPropertyConditionSet& conditionSet() const { return m_conditionSet; }
    
private:
    Kind m_kind;
    PropertyOffset m_offset;
    ObjectPropertyConditionSet m_conditionSet;
};

} // namespace JSC

#endif // ComplexGetStatus_h

