1/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef SymbolTable_h
30#define SymbolTable_h
31
32#include "JSObject.h"
33#include "UString.h"
34#include <wtf/AlwaysInline.h>
35
36namespace JSC {
37
38    static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
39
40    // The bit twiddling in this class assumes that every register index is a
41    // reasonably small positive or negative number, and therefore has its high
42    // four bits all set or all unset.
43
44    struct SymbolTableEntry {
45        SymbolTableEntry()
46            : m_bits(0)
47        {
48        }
49
50        SymbolTableEntry(int index)
51        {
52            ASSERT(isValidIndex(index));
53            pack(index, false, false);
54        }
55
56        SymbolTableEntry(int index, unsigned attributes)
57        {
58            ASSERT(isValidIndex(index));
59            pack(index, attributes & ReadOnly, attributes & DontEnum);
60        }
61
62        bool isNull() const
63        {
64            return !m_bits;
65        }
66
67        int getIndex() const
68        {
69            return m_bits >> FlagBits;
70        }
71
72        unsigned getAttributes() const
73        {
74            unsigned attributes = 0;
75            if (m_bits & ReadOnlyFlag)
76                attributes |= ReadOnly;
77            if (m_bits & DontEnumFlag)
78                attributes |= DontEnum;
79            return attributes;
80        }
81
82        void setAttributes(unsigned attributes)
83        {
84            pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
85        }
86
87        bool isReadOnly() const
88        {
89            return m_bits & ReadOnlyFlag;
90        }
91
92    private:
93        static const unsigned ReadOnlyFlag = 0x1;
94        static const unsigned DontEnumFlag = 0x2;
95        static const unsigned NotNullFlag = 0x4;
96        static const unsigned FlagBits = 3;
97
98        void pack(int index, bool readOnly, bool dontEnum)
99        {
100            m_bits = (index << FlagBits) | NotNullFlag;
101            if (readOnly)
102                m_bits |= ReadOnlyFlag;
103            if (dontEnum)
104                m_bits |= DontEnumFlag;
105        }
106
107        bool isValidIndex(int index)
108        {
109            return ((index << FlagBits) >> FlagBits) == index;
110        }
111
112        int m_bits;
113    };
114
115    struct SymbolTableIndexHashTraits {
116        typedef SymbolTableEntry TraitType;
117        static SymbolTableEntry emptyValue() { return SymbolTableEntry(); }
118        static const bool emptyValueIsZero = true;
119        static const bool needsDestruction = false;
120    };
121
122    typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, SymbolTableIndexHashTraits> SymbolTable;
123
124    class SharedSymbolTable : public SymbolTable, public RefCounted<SharedSymbolTable> {
125        WTF_MAKE_FAST_ALLOCATED;
126    public:
127        static PassRefPtr<SharedSymbolTable> create() { return adoptRef(new SharedSymbolTable); }
128    private:
129        SharedSymbolTable() { }
130    };
131
132} // namespace JSC
133
134#endif // SymbolTable_h
135