/*
 *  Copyright (C) 2005-2020 Apple Inc. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include "DOMAnnotation.h"
#include "DisallowVMEntry.h"
#include "GetVM.h"
#include "JSCJSValue.h"
#include "PropertyName.h"
#include "PropertyOffset.h"
#include "ScopeOffset.h"
#include <wtf/Assertions.h>
#include <wtf/ForbidHeapAllocation.h>

namespace JSC {
class GetterSetter;
class JSObject;
class JSModuleEnvironment;

// ECMA 262-3 8.6.1
// Property attributes
enum class PropertyAttribute : unsigned {
    None              = 0,
    ReadOnly          = 1 << 1,  // property can be only read, not written
    DontEnum          = 1 << 2,  // property doesn't appear in (for .. in ..)
    DontDelete        = 1 << 3,  // property can't be deleted
    Accessor          = 1 << 4,  // property is a getter/setter
    CustomAccessor    = 1 << 5,
    CustomValue       = 1 << 6,
    CustomAccessorOrValue = CustomAccessor | CustomValue,
    AccessorOrCustomAccessorOrValue = Accessor | CustomAccessor | CustomValue,
    ReadOnlyOrAccessorOrCustomAccessor = ReadOnly | Accessor | CustomAccessor,

    // Things that are used by static hashtables are not in the attributes byte in PropertyMapEntry.
    Function          = 1 << 8,  // property is a function - only used by static hashtables
    Builtin           = 1 << 9,  // property is a builtin function - only used by static hashtables
    ConstantInteger   = 1 << 10, // property is a constant integer - only used by static hashtables
    CellProperty      = 1 << 11, // property is a lazy property - only used by static hashtables
    ClassStructure    = 1 << 12, // property is a lazy class structure - only used by static hashtables
    PropertyCallback  = 1 << 13, // property that is a lazy property callback - only used by static hashtables
    DOMAttribute      = 1 << 14, // property is a simple DOM attribute - only used by static hashtables
    DOMJITAttribute   = 1 << 15, // property is a DOM JIT attribute - only used by static hashtables
    DOMJITFunction    = 1 << 16, // property is a DOM JIT function - only used by static hashtables
    BuiltinOrFunction = Builtin | Function, // helper only used by static hashtables
    BuiltinOrFunctionOrLazyProperty = Builtin | Function | CellProperty | ClassStructure | PropertyCallback, // helper only used by static hashtables
    BuiltinOrFunctionOrAccessorOrLazyProperty = Builtin | Function | Accessor | CellProperty | ClassStructure | PropertyCallback, // helper only used by static hashtables
    BuiltinOrFunctionOrAccessorOrLazyPropertyOrConstant = Builtin | Function | Accessor | CellProperty | ClassStructure | PropertyCallback | ConstantInteger // helper only used by static hashtables
};

static constexpr unsigned operator| (PropertyAttribute a, PropertyAttribute b) { return static_cast<unsigned>(a) | static_cast<unsigned>(b); }
static constexpr unsigned operator| (unsigned a, PropertyAttribute b) { return a | static_cast<unsigned>(b); }
static constexpr unsigned operator| (PropertyAttribute a, unsigned b) { return static_cast<unsigned>(a) | b; }
static constexpr unsigned operator&(unsigned a, PropertyAttribute b) { return a & static_cast<unsigned>(b); }
static constexpr bool operator<(PropertyAttribute a, PropertyAttribute b) { return static_cast<unsigned>(a) < static_cast<unsigned>(b); }
static constexpr unsigned operator~(PropertyAttribute a) { return ~static_cast<unsigned>(a); }
static constexpr bool operator<(PropertyAttribute a, unsigned b) { return static_cast<unsigned>(a) < b; }
static inline unsigned& operator|=(unsigned& a, PropertyAttribute b) { return a |= static_cast<unsigned>(b); }

enum CacheabilityType : uint8_t {
    CachingDisallowed,
    CachingAllowed
};

inline unsigned attributesForStructure(unsigned attributes)
{
    // The attributes that are used just for the static hashtable are at bit 8 and higher.
    return static_cast<uint8_t>(attributes);
}

using GetValueFunc = EncodedJSValue(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue thisValue, PropertyName);
using GetValueFuncWithPtr = EncodedJSValue(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue thisValue, PropertyName, void*);

using PutValueFunc = bool (JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue baseObject, EncodedJSValue value, PropertyName);
using PutValueFuncWithPtr = bool (JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue baseObject, EncodedJSValue value, PropertyName, void*);

class PropertySlot {

    // We rely on PropertySlot being stack allocated when used. This is needed
    // because we rely on some of its fields being a GC root. For example, it
    // may be the only thing that points to the GetterSetter property it has.
    WTF_FORBID_HEAP_ALLOCATION;

    enum PropertyType : uint8_t {
        TypeUnset,
        TypeValue,
        TypeGetter,
        TypeCustom,
    };

public:
    enum class InternalMethodType : uint8_t {
        Get, // [[Get]] internal method in the spec.
        HasProperty, // [[HasProperty]] internal method in the spec.
        GetOwnProperty, // [[GetOwnProperty]] internal method in the spec.
        VMInquiry, // Our VM is just poking around. When this is the InternalMethodType, getOwnPropertySlot is not allowed to do user observable actions.
    };

    enum class AdditionalDataType : uint8_t {
        None,
        DOMAttribute, // Annotated with DOMAttribute information.
        ModuleNamespace, // ModuleNamespaceObject's environment access.
    };

    explicit PropertySlot(const JSValue thisValue, InternalMethodType internalMethodType, VM* vmForInquiry = nullptr)
        : m_thisValue(thisValue)
        , m_internalMethodType(internalMethodType)
    {
        if (isVMInquiry())
            disallowVMEntry.emplace(*vmForInquiry);
    }

    using GetValueFunc = JSC::GetValueFunc;
    using GetValueFuncWithPtr = JSC::GetValueFuncWithPtr;

    JSValue getValue(JSGlobalObject*, PropertyName) const;
    JSValue getValue(JSGlobalObject*, uint64_t propertyName) const;
    JSValue getPureResult() const;

    bool isCacheable() const { return isUnset() || m_cacheability == CachingAllowed; }
    bool isUnset() const { return m_propertyType == TypeUnset; }
    bool isValue() const { return m_propertyType == TypeValue; }
    bool isAccessor() const { return m_propertyType == TypeGetter; }
    bool isCustom() const { return m_propertyType == TypeCustom; }
    bool isCacheableValue() const { return isCacheable() && isValue(); }
    bool isCacheableGetter() const { return isCacheable() && isAccessor(); }
    bool isCacheableCustom() const { return isCacheable() && isCustom(); }
    void setIsTaintedByOpaqueObject() { m_isTaintedByOpaqueObject = true; }
    bool isTaintedByOpaqueObject() const { return m_isTaintedByOpaqueObject; }

    InternalMethodType internalMethodType() const { return m_internalMethodType; }
    bool isVMInquiry() const { return m_internalMethodType == InternalMethodType::VMInquiry; }

    void disableCaching()
    {
        m_cacheability = CachingDisallowed;
    }

    unsigned attributes() const { return m_attributes; }

    PropertyOffset cachedOffset() const
    {
        ASSERT(isCacheable());
        return m_offset;
    }

    GetterSetter* getterSetter() const
    {
        ASSERT(isAccessor());
        return m_data.getter.getterSetter;
    }

    GetValueFunc customGetter() const
    {
        ASSERT(isCustom());
        return m_data.custom.getValue;
    }

    PutValueFunc customSetter() const
    {
        ASSERT(isCustom());
        return m_data.custom.putValue;
    }

    JSObject* slotBase() const
    {
        return m_slotBase;
    }

    WatchpointSet* watchpointSet() const
    {
        return m_watchpointSet;
    }

    std::optional<DOMAttributeAnnotation> domAttribute() const
    {
        if (m_additionalDataType == AdditionalDataType::DOMAttribute)
            return m_additionalData.domAttribute;
        return std::nullopt;
    }

    struct ModuleNamespaceSlot {
        JSModuleEnvironment* environment;
        unsigned scopeOffset;
    };

    std::optional<ModuleNamespaceSlot> moduleNamespaceSlot() const
    {
        if (m_additionalDataType == AdditionalDataType::ModuleNamespace)
            return m_additionalData.moduleNamespaceSlot;
        return std::nullopt;
    }

    void setValue(JSObject* slotBase, unsigned attributes, JSValue value)
    {
        ASSERT(attributes == attributesForStructure(attributes));
        
        m_data.value = JSValue::encode(value);
        m_attributes = attributes;

        ASSERT(slotBase);
        m_slotBase = slotBase;
        m_propertyType = TypeValue;

        ASSERT(m_cacheability == CachingDisallowed);
    }
    
    void setValue(JSObject* slotBase, unsigned attributes, JSValue value, PropertyOffset offset)
    {
        ASSERT(attributes == attributesForStructure(attributes));
        
        ASSERT(value);
        m_data.value = JSValue::encode(value);
        m_attributes = attributes;

        ASSERT(slotBase);
        m_slotBase = slotBase;
        m_propertyType = TypeValue;
        m_offset = offset;

        m_cacheability = CachingAllowed;
    }

    void setValue(JSString*, unsigned attributes, JSValue value)
    {
        ASSERT(attributes == attributesForStructure(attributes));
        
        ASSERT(value);
        m_data.value = JSValue::encode(value);
        m_attributes = attributes;

        m_slotBase = nullptr;
        m_propertyType = TypeValue;

        ASSERT(m_cacheability == CachingDisallowed);
    }

    void setValueModuleNamespace(JSObject* slotBase, unsigned attributes, JSValue value, JSModuleEnvironment* environment, ScopeOffset scopeOffset)
    {
        setValue(slotBase, attributes, value);
        m_additionalDataType = AdditionalDataType::ModuleNamespace;
        m_additionalData.moduleNamespaceSlot.environment = environment;
        m_additionalData.moduleNamespaceSlot.scopeOffset = scopeOffset.offset();
    }

    void setCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, PutValueFunc putValue = nullptr)
    {
        ASSERT(attributes == attributesForStructure(attributes));
        
        ASSERT(getValue);
        assertIsCFunctionPtr(getValue);
        m_data.custom.getValue = getValue;
        assertIsNullOrCFunctionPtr(putValue);
        m_data.custom.putValue = putValue;
        m_attributes = attributes;

        ASSERT(slotBase);
        m_slotBase = slotBase;
        m_propertyType = TypeCustom;
        ASSERT(m_cacheability == CachingDisallowed);
    }

    void setCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, PutValueFunc putValue, DOMAttributeAnnotation domAttribute)
    {
        setCustom(slotBase, attributes, getValue, putValue);
        m_additionalDataType = AdditionalDataType::DOMAttribute;
        m_additionalData.domAttribute = domAttribute;
    }
    
    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, PutValueFunc putValue = nullptr)
    {
        ASSERT(attributes == attributesForStructure(attributes));
        
        ASSERT(getValue);
        assertIsCFunctionPtr(getValue);
        m_data.custom.getValue = getValue;
        assertIsNullOrCFunctionPtr(putValue);
        m_data.custom.putValue = putValue;
        m_attributes = attributes;

        ASSERT(slotBase);
        m_slotBase = slotBase;
        m_propertyType = TypeCustom;

        m_cacheability = CachingAllowed;
    }

    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, PutValueFunc putValue, DOMAttributeAnnotation domAttribute)
    {
        setCacheableCustom(slotBase, attributes, getValue, putValue);
        m_additionalDataType = AdditionalDataType::DOMAttribute;
        m_additionalData.domAttribute = domAttribute;
    }

    void setGetterSlot(JSObject* slotBase, unsigned attributes, GetterSetter* getterSetter)
    {
        ASSERT(attributes == attributesForStructure(attributes));
        
        ASSERT(getterSetter);
        m_data.getter.getterSetter = getterSetter;
        m_attributes = attributes;

        ASSERT(slotBase);
        m_slotBase = slotBase;
        m_propertyType = TypeGetter;

        ASSERT(m_cacheability == CachingDisallowed);
    }

    void setCacheableGetterSlot(JSObject* slotBase, unsigned attributes, GetterSetter* getterSetter, PropertyOffset offset)
    {
        ASSERT(attributes == attributesForStructure(attributes));
        
        ASSERT(getterSetter);
        m_data.getter.getterSetter = getterSetter;
        m_attributes = attributes;

        ASSERT(slotBase);
        m_slotBase = slotBase;
        m_propertyType = TypeGetter;
        m_offset = offset;

        m_cacheability = CachingAllowed;
    }

    JSValue thisValue() const
    {
        return m_thisValue;
    }

    void setThisValue(JSValue thisValue)
    {
        m_thisValue = thisValue;
    }

    void setUndefined()
    {
        m_data.value = JSValue::encode(jsUndefined());
        m_attributes = PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete | PropertyAttribute::DontEnum;

        m_slotBase = nullptr;
        m_propertyType = TypeValue;
    }

    void setWatchpointSet(WatchpointSet& set)
    {
        ASSERT(set.isStillValid());
        m_watchpointSet = &set;
    }

private:
    JS_EXPORT_PRIVATE JSValue functionGetter(JSGlobalObject*) const;
    JS_EXPORT_PRIVATE JSValue customGetter(VM&, PropertyName) const;

    union {
        EncodedJSValue value;
        struct {
            GetterSetter* getterSetter;
        } getter;
        struct {
            GetValueFunc getValue;
            PutValueFunc putValue;
        } custom;
    } m_data;

    unsigned m_attributes { 0 };
    PropertyOffset m_offset { invalidOffset };
    JSValue m_thisValue;
    JSObject* m_slotBase { nullptr };
    WatchpointSet* m_watchpointSet { nullptr };
    CacheabilityType m_cacheability { CachingDisallowed };
    PropertyType m_propertyType { TypeUnset };
    InternalMethodType m_internalMethodType;
    AdditionalDataType m_additionalDataType { AdditionalDataType::None };
    bool m_isTaintedByOpaqueObject { false };
public:
    std::optional<DisallowVMEntry> disallowVMEntry;
private:
    union {
        DOMAttributeAnnotation domAttribute;
        ModuleNamespaceSlot moduleNamespaceSlot;
    } m_additionalData { { nullptr, nullptr } };
};

ALWAYS_INLINE JSValue PropertySlot::getValue(JSGlobalObject* globalObject, PropertyName propertyName) const
{
    if (m_propertyType == TypeValue)
        return JSValue::decode(m_data.value);
    if (m_propertyType == TypeGetter)
        return functionGetter(globalObject);
    return customGetter(getVM(globalObject), propertyName);
}

ALWAYS_INLINE JSValue PropertySlot::getValue(JSGlobalObject* globalObject, uint64_t propertyName) const
{
    VM& vm = getVM(globalObject);
    if (m_propertyType == TypeValue)
        return JSValue::decode(m_data.value);
    if (m_propertyType == TypeGetter)
        return functionGetter(globalObject);
    return customGetter(getVM(globalObject), Identifier::from(vm, propertyName));
}

} // namespace JSC
