2 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
25 #include <wtf/ThreadSpecific.h>
26 #include <wtf/WTFThreadData.h>
27 #include <wtf/text/CString.h>
28 #include <wtf/text/WTFString.h>
35 friend class Structure
;
38 enum EmptyIdentifierFlag
{ EmptyIdentifier
};
39 Identifier(EmptyIdentifierFlag
) : m_string(StringImpl::empty()) { ASSERT(m_string
.impl()->isAtomic()); }
41 // Only to be used with string literals.
42 template<unsigned charactersCount
>
43 Identifier(ExecState
* exec
, const char (&characters
)[charactersCount
]) : m_string(add(exec
, characters
)) { ASSERT(m_string
.impl()->isAtomic()); }
44 template<unsigned charactersCount
>
45 Identifier(VM
* vm
, const char (&characters
)[charactersCount
]) : m_string(add(vm
, characters
)) { ASSERT(m_string
.impl()->isAtomic()); }
47 Identifier(ExecState
* exec
, StringImpl
* rep
) : m_string(add(exec
, rep
)) { ASSERT(m_string
.impl()->isAtomic()); }
48 Identifier(ExecState
* exec
, const String
& s
) : m_string(add(exec
, s
.impl())) { ASSERT(m_string
.impl()->isAtomic()); }
50 Identifier(VM
* vm
, const LChar
* s
, int length
) : m_string(add(vm
, s
, length
)) { ASSERT(m_string
.impl()->isAtomic()); }
51 Identifier(VM
* vm
, const UChar
* s
, int length
) : m_string(add(vm
, s
, length
)) { ASSERT(m_string
.impl()->isAtomic()); }
52 Identifier(VM
* vm
, StringImpl
* rep
) : m_string(add(vm
, rep
)) { ASSERT(m_string
.impl()->isAtomic()); }
53 Identifier(VM
* vm
, const String
& s
) : m_string(add(vm
, s
.impl())) { ASSERT(m_string
.impl()->isAtomic()); }
55 const String
& string() const { return m_string
; }
56 StringImpl
* impl() const { return m_string
.impl(); }
58 int length() const { return m_string
.length(); }
60 CString
ascii() const { return m_string
.ascii(); }
61 CString
utf8() const { return m_string
.utf8(); }
63 static Identifier
from(const PrivateName
& name
)
66 result
.m_string
= name
.uid();
70 static Identifier
createLCharFromUChar(VM
* vm
, const UChar
* s
, int length
) { return Identifier(vm
, add8(vm
, s
, length
)); }
72 JS_EXPORT_PRIVATE
static Identifier
from(ExecState
* exec
, unsigned y
);
73 JS_EXPORT_PRIVATE
static Identifier
from(ExecState
* exec
, int y
);
74 static Identifier
from(ExecState
* exec
, double y
);
75 static Identifier
from(VM
*, unsigned y
);
76 static Identifier
from(VM
*, int y
);
77 static Identifier
from(VM
*, double y
);
79 bool isNull() const { return m_string
.isNull(); }
80 bool isEmpty() const { return m_string
.isEmpty(); }
82 friend bool operator==(const Identifier
&, const Identifier
&);
83 friend bool operator!=(const Identifier
&, const Identifier
&);
85 friend bool operator==(const Identifier
&, const LChar
*);
86 friend bool operator==(const Identifier
&, const char*);
87 friend bool operator!=(const Identifier
&, const LChar
*);
88 friend bool operator!=(const Identifier
&, const char*);
90 static bool equal(const StringImpl
*, const LChar
*);
91 static inline bool equal(const StringImpl
*a
, const char*b
) { return Identifier::equal(a
, reinterpret_cast<const LChar
*>(b
)); };
92 static bool equal(const StringImpl
*, const LChar
*, unsigned length
);
93 static bool equal(const StringImpl
*, const UChar
*, unsigned length
);
94 static bool equal(const StringImpl
* a
, const StringImpl
* b
) { return ::equal(a
, b
); }
96 // Only to be used with string literals.
97 JS_EXPORT_PRIVATE
static PassRef
<StringImpl
> add(VM
*, const char*);
98 JS_EXPORT_PRIVATE
static PassRef
<StringImpl
> add(ExecState
*, const char*);
103 template <typename CharType
>
104 ALWAYS_INLINE
static uint32_t toUInt32FromCharacters(const CharType
* characters
, unsigned length
, bool& ok
);
106 static bool equal(const Identifier
& a
, const Identifier
& b
) { return a
.m_string
.impl() == b
.m_string
.impl(); }
107 static bool equal(const Identifier
& a
, const LChar
* b
) { return equal(a
.m_string
.impl(), b
); }
109 template <typename T
> static PassRef
<StringImpl
> add(VM
*, const T
*, int length
);
110 static PassRef
<StringImpl
> add8(VM
*, const UChar
*, int length
);
111 template <typename T
> ALWAYS_INLINE
static bool canUseSingleCharacterString(T
);
113 static PassRef
<StringImpl
> add(ExecState
*, StringImpl
*);
114 static PassRef
<StringImpl
> add(VM
*, StringImpl
*);
116 JS_EXPORT_PRIVATE
static void checkCurrentAtomicStringTable(ExecState
*);
117 JS_EXPORT_PRIVATE
static void checkCurrentAtomicStringTable(VM
*);
120 template <> ALWAYS_INLINE
bool Identifier::canUseSingleCharacterString(LChar
)
122 ASSERT(maxSingleCharacterString
== 0xff);
126 template <> ALWAYS_INLINE
bool Identifier::canUseSingleCharacterString(UChar c
)
128 return (c
<= maxSingleCharacterString
);
131 template <typename T
>
132 PassRef
<StringImpl
> Identifier::add(VM
* vm
, const T
* s
, int length
)
136 if (canUseSingleCharacterString(c
))
137 return *vm
->smallStrings
.singleCharacterStringRep(c
);
140 return *StringImpl::empty();
142 return *AtomicString::add(s
, length
);
145 inline bool operator==(const Identifier
& a
, const Identifier
& b
)
147 return Identifier::equal(a
, b
);
150 inline bool operator!=(const Identifier
& a
, const Identifier
& b
)
152 return !Identifier::equal(a
, b
);
155 inline bool operator==(const Identifier
& a
, const LChar
* b
)
157 return Identifier::equal(a
, b
);
160 inline bool operator==(const Identifier
& a
, const char* b
)
162 return Identifier::equal(a
, reinterpret_cast<const LChar
*>(b
));
165 inline bool operator!=(const Identifier
& a
, const LChar
* b
)
167 return !Identifier::equal(a
, b
);
170 inline bool operator!=(const Identifier
& a
, const char* b
)
172 return !Identifier::equal(a
, reinterpret_cast<const LChar
*>(b
));
175 inline bool Identifier::equal(const StringImpl
* r
, const LChar
* s
)
177 return WTF::equal(r
, s
);
180 inline bool Identifier::equal(const StringImpl
* r
, const LChar
* s
, unsigned length
)
182 return WTF::equal(r
, s
, length
);
185 inline bool Identifier::equal(const StringImpl
* r
, const UChar
* s
, unsigned length
)
187 return WTF::equal(r
, s
, length
);
190 struct IdentifierRepHash
: PtrHash
<RefPtr
<StringImpl
>> {
191 static unsigned hash(const RefPtr
<StringImpl
>& key
) { return key
->existingHash(); }
192 static unsigned hash(StringImpl
* key
) { return key
->existingHash(); }
195 struct IdentifierMapIndexHashTraits
: HashTraits
<int> {
196 static int emptyValue() { return std::numeric_limits
<int>::max(); }
197 static const bool emptyValueIsZero
= false;
200 typedef HashMap
<RefPtr
<StringImpl
>, int, IdentifierRepHash
, HashTraits
<RefPtr
<StringImpl
>>, IdentifierMapIndexHashTraits
> IdentifierMap
;
201 typedef HashMap
<StringImpl
*, int, IdentifierRepHash
, HashTraits
<StringImpl
*>, IdentifierMapIndexHashTraits
> BorrowedIdentifierMap
;
207 template <> struct VectorTraits
<JSC::Identifier
> : SimpleClassVectorTraits
{ };
211 #endif // Identifier_h