/*
 * Copyright (C) 2007, 2008, 2012 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 SymbolTable_h
#define SymbolTable_h

#include "JSObject.h"
#include "Watchpoint.h"
#include <wtf/AlwaysInline.h>
#include <wtf/HashTraits.h>
#include <wtf/text/StringImpl.h>

namespace JSC {

    class Watchpoint;
    class WatchpointSet;

    struct SlowArgument {
        enum Status {
            Normal = 0,
            Captured = 1,
            Deleted = 2
        };

        SlowArgument()
            : status(Normal)
            , index(0)
        {
        }

        Status status;
        int index; // If status is 'Deleted', index is bogus.
    };

    static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }

    // The bit twiddling in this class assumes that every register index is a
    // reasonably small positive or negative number, and therefore has its high
    // four bits all set or all unset.

    // In addition to implementing semantics-mandated variable attributes and
    // implementation-mandated variable indexing, this class also implements
    // watchpoints to be used for JIT optimizations. Because watchpoints are
    // meant to be relatively rare, this class optimizes heavily for the case
    // that they are not being used. To that end, this class uses the thin-fat
    // idiom: either it is thin, in which case it contains an in-place encoded
    // word that consists of attributes, the index, and a bit saying that it is
    // thin; or it is fat, in which case it contains a pointer to a malloc'd
    // data structure and a bit saying that it is fat. The malloc'd data
    // structure will be malloced a second time upon copy, to preserve the
    // property that in-place edits to SymbolTableEntry do not manifest in any
    // copies. However, the malloc'd FatEntry data structure contains a ref-
    // counted pointer to a shared WatchpointSet. Thus, in-place edits of the
    // WatchpointSet will manifest in all copies. Here's a picture:
    //
    // SymbolTableEntry --> FatEntry --> WatchpointSet
    //
    // If you make a copy of a SymbolTableEntry, you will have:
    //
    // original: SymbolTableEntry --> FatEntry --> WatchpointSet
    // copy:     SymbolTableEntry --> FatEntry -----^

    struct SymbolTableEntry {
        // Use the SymbolTableEntry::Fast class, either via implicit cast or by calling
        // getFast(), when you (1) only care about isNull(), getIndex(), and isReadOnly(),
        // and (2) you are in a hot path where you need to minimize the number of times
        // that you branch on isFat() when getting the bits().
        class Fast {
        public:
            Fast()
                : m_bits(0)
            {
            }
            
            ALWAYS_INLINE Fast(const SymbolTableEntry& entry)
                : m_bits(entry.bits())
            {
            }
        
            bool isNull() const
            {
                return !m_bits;
            }

            int getIndex() const
            {
                return static_cast<int>(m_bits >> FlagBits);
            }
        
            bool isReadOnly() const
            {
                return m_bits & ReadOnlyFlag;
            }
            
            unsigned getAttributes() const
            {
                unsigned attributes = 0;
                if (m_bits & ReadOnlyFlag)
                    attributes |= ReadOnly;
                if (m_bits & DontEnumFlag)
                    attributes |= DontEnum;
                return attributes;
            }

            bool isFat() const
            {
                return m_bits & FatFlag;
            }
            
        private:
            friend struct SymbolTableEntry;
            intptr_t m_bits;
        };

        SymbolTableEntry()
            : m_bits(0)
        {
        }

        SymbolTableEntry(int index)
            : m_bits(0)
        {
            ASSERT(isValidIndex(index));
            pack(index, false, false);
        }

        SymbolTableEntry(int index, unsigned attributes)
            : m_bits(0)
        {
            ASSERT(isValidIndex(index));
            pack(index, attributes & ReadOnly, attributes & DontEnum);
        }
        
        ~SymbolTableEntry()
        {
            freeFatEntry();
        }
        
        SymbolTableEntry(const SymbolTableEntry& other)
            : m_bits(0)
        {
            *this = other;
        }
        
        SymbolTableEntry& operator=(const SymbolTableEntry& other)
        {
            if (UNLIKELY(other.isFat()))
                return copySlow(other);
            freeFatEntry();
            m_bits = other.m_bits;
            return *this;
        }
        
        bool isNull() const
        {
            return !bits();
        }

        int getIndex() const
        {
            return static_cast<int>(bits() >> FlagBits);
        }
        
        ALWAYS_INLINE Fast getFast() const
        {
            return Fast(*this);
        }
        
        ALWAYS_INLINE Fast getFast(bool& wasFat) const
        {
            Fast result;
            wasFat = isFat();
            if (wasFat)
                result.m_bits = fatEntry()->m_bits;
            else
                result.m_bits = m_bits;
            return result;
        }
        
        unsigned getAttributes() const
        {
            return getFast().getAttributes();
        }

        void setAttributes(unsigned attributes)
        {
            pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
        }

        bool isReadOnly() const
        {
            return bits() & ReadOnlyFlag;
        }
        
        bool couldBeWatched();
        
        // Notify an opportunity to create a watchpoint for a variable. This is
        // idempotent and fail-silent. It is idempotent in the sense that if
        // a watchpoint set had already been created, then another one will not
        // be created. Hence two calls to this method have the same effect as
        // one call. It is also fail-silent, in the sense that if a watchpoint
        // set had been created and had already been invalidated, then this will
        // just return. This means that couldBeWatched() may return false even
        // immediately after a call to attemptToWatch().
        void attemptToWatch();
        
        bool* addressOfIsWatched();
        
        void addWatchpoint(Watchpoint*);
        
        WatchpointSet* watchpointSet()
        {
            return fatEntry()->m_watchpoints.get();
        }
        
        ALWAYS_INLINE void notifyWrite()
        {
            if (LIKELY(!isFat()))
                return;
            notifyWriteSlow();
        }
        
    private:
        static const intptr_t FatFlag = 0x1;
        static const intptr_t ReadOnlyFlag = 0x2;
        static const intptr_t DontEnumFlag = 0x4;
        static const intptr_t NotNullFlag = 0x8;
        static const intptr_t FlagBits = 4;
        
        class FatEntry {
            WTF_MAKE_FAST_ALLOCATED;
        public:
            FatEntry(intptr_t bits)
                : m_bits(bits | FatFlag)
            {
            }
            
            intptr_t m_bits; // always has FatFlag set and exactly matches what the bits would have been if this wasn't fat.
            
            RefPtr<WatchpointSet> m_watchpoints;
        };
        
        SymbolTableEntry& copySlow(const SymbolTableEntry&);
        JS_EXPORT_PRIVATE void notifyWriteSlow();
        
        bool isFat() const
        {
            return m_bits & FatFlag;
        }
        
        const FatEntry* fatEntry() const
        {
            ASSERT(isFat());
            return bitwise_cast<const FatEntry*>(m_bits & ~FatFlag);
        }
        
        FatEntry* fatEntry()
        {
            ASSERT(isFat());
            return bitwise_cast<FatEntry*>(m_bits & ~FatFlag);
        }
        
        FatEntry* inflate()
        {
            if (LIKELY(isFat()))
                return fatEntry();
            return inflateSlow();
        }
        
        FatEntry* inflateSlow();
        
        ALWAYS_INLINE intptr_t bits() const
        {
            if (isFat())
                return fatEntry()->m_bits;
            return m_bits;
        }
        
        ALWAYS_INLINE intptr_t& bits()
        {
            if (isFat())
                return fatEntry()->m_bits;
            return m_bits;
        }
        
        void freeFatEntry()
        {
            if (LIKELY(!isFat()))
                return;
            freeFatEntrySlow();
        }
        
        JS_EXPORT_PRIVATE void freeFatEntrySlow();

        void pack(int index, bool readOnly, bool dontEnum)
        {
            intptr_t& bitsRef = bits();
            bitsRef = (static_cast<intptr_t>(index) << FlagBits) | NotNullFlag;
            if (readOnly)
                bitsRef |= ReadOnlyFlag;
            if (dontEnum)
                bitsRef |= DontEnumFlag;
        }
        
        bool isValidIndex(int index)
        {
            return ((static_cast<intptr_t>(index) << FlagBits) >> FlagBits) == static_cast<intptr_t>(index);
        }

        intptr_t m_bits;
    };

    struct SymbolTableIndexHashTraits : HashTraits<SymbolTableEntry> {
        static const bool emptyValueIsZero = true;
        static const bool needsDestruction = true;
    };

    typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, SymbolTableIndexHashTraits> SymbolTable;

    class SharedSymbolTable : public JSCell, public SymbolTable {
    public:
        typedef JSCell Base;

        static SharedSymbolTable* create(JSGlobalData& globalData)
        {
            SharedSymbolTable* sharedSymbolTable = new (NotNull, allocateCell<SharedSymbolTable>(globalData.heap)) SharedSymbolTable(globalData);
            sharedSymbolTable->finishCreation(globalData);
            return sharedSymbolTable;
        }
        static const bool needsDestruction = true;
        static const bool hasImmortalStructure = true;
        static void destroy(JSCell*);

        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
        {
            return Structure::create(globalData, globalObject, prototype, TypeInfo(LeafType, StructureFlags), &s_info);
        }

        bool usesNonStrictEval() { return m_usesNonStrictEval; }
        void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }

        int captureStart() { return m_captureStart; }
        void setCaptureStart(int captureStart) { m_captureStart = captureStart; }

        int captureEnd() { return m_captureEnd; }
        void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }

        int captureCount() { return m_captureEnd - m_captureStart; }

        int parameterCount() { return m_parameterCountIncludingThis - 1; }
        int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
        void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }

        // 0 if we don't capture any arguments; parameterCount() in length if we do.
        const SlowArgument* slowArguments() { return m_slowArguments.get(); }
        void setSlowArguments(PassOwnArrayPtr<SlowArgument> slowArguments) { m_slowArguments = slowArguments; }

        DECLARE_EXPORTED_CLASSINFO();

    private:
        SharedSymbolTable(JSGlobalData& globalData)
            : JSCell(globalData, globalData.sharedSymbolTableStructure.get())
            , m_parameterCountIncludingThis(0)
            , m_usesNonStrictEval(false)
            , m_captureStart(0)
            , m_captureEnd(0)
        {
        }

        int m_parameterCountIncludingThis;
        bool m_usesNonStrictEval;

        int m_captureStart;
        int m_captureEnd;

        OwnArrayPtr<SlowArgument> m_slowArguments;
    };

} // namespace JSC

#endif // SymbolTable_h
