1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jsatominlines_h
8 #define jsatominlines_h
12 #include "mozilla/PodOperations.h"
13 #include "mozilla/RangedPtr.h"
18 #include "vm/String.h"
21 js::AtomStateEntry::asPtr() const
24 JSAtom
* atom
= reinterpret_cast<JSAtom
*>(bits
& NO_TAG_MASK
);
25 JSString::readBarrier(atom
);
32 AtomToId(JSAtom
* atom
)
34 JS_STATIC_ASSERT(JSID_INT_MIN
== 0);
37 if (atom
->isIndex(&index
) && index
<= JSID_INT_MAX
)
38 return INT_TO_JSID(int32_t(index
));
40 return JSID_FROM_BITS(size_t(atom
));
44 ValueToIdPure(const Value
& v
, jsid
* id
)
47 if (ValueFitsInInt32(v
, &i
) && INT_FITS_IN_JSID(i
)) {
53 *id
= SYMBOL_TO_JSID(v
.toSymbol());
57 if (!v
.isString() || !v
.toString()->isAtom())
60 *id
= AtomToId(&v
.toString()->asAtom());
64 template <AllowGC allowGC
>
66 ValueToId(JSContext
* cx
, typename MaybeRooted
<Value
, allowGC
>::HandleType v
,
67 typename MaybeRooted
<jsid
, allowGC
>::MutableHandleType idp
)
70 if (ValueFitsInInt32(v
, &i
) && INT_FITS_IN_JSID(i
)) {
71 idp
.set(INT_TO_JSID(i
));
76 idp
.set(SYMBOL_TO_JSID(v
.toSymbol()));
80 JSAtom
* atom
= ToAtom
<allowGC
>(cx
, v
);
84 idp
.set(AtomToId(atom
));
89 * Write out character representing |index| to the memory just before |end|.
90 * Thus |*end| is not touched, but |end[-1]| and earlier are modified as
91 * appropriate. There must be at least js::UINT32_CHAR_BUFFER_LENGTH elements
92 * before |end| to avoid buffer underflow. The start of the characters written
93 * is returned and is necessarily before |end|.
96 inline mozilla::RangedPtr
<T
>
97 BackfillIndexInCharBuffer(uint32_t index
, mozilla::RangedPtr
<T
> end
)
101 * Assert that the buffer we're filling will hold as many characters as we
102 * could write out, by dereferencing the index that would hold the most
105 (void) *(end
- UINT32_CHAR_BUFFER_LENGTH
);
109 uint32_t next
= index
/ 10, digit
= index
% 10;
110 *--end
= '0' + digit
;
118 IndexToIdSlow(ExclusiveContext
* cx
, uint32_t index
, MutableHandleId idp
);
121 IndexToId(ExclusiveContext
* cx
, uint32_t index
, MutableHandleId idp
)
123 if (index
<= JSID_INT_MAX
) {
124 idp
.set(INT_TO_JSID(index
));
128 return IndexToIdSlow(cx
, index
, idp
);
131 static MOZ_ALWAYS_INLINE JSFlatString
*
132 IdToString(JSContext
* cx
, jsid id
)
134 if (JSID_IS_STRING(id
))
135 return JSID_TO_ATOM(id
);
137 if (MOZ_LIKELY(JSID_IS_INT(id
)))
138 return Int32ToString
<CanGC
>(cx
, JSID_TO_INT(id
));
140 RootedValue
idv(cx
, IdToValue(id
));
141 JSString
* str
= ToStringSlow
<CanGC
>(cx
, idv
);
145 return str
->ensureFlat(cx
);
149 AtomHasher::Lookup::Lookup(const JSAtom
* atom
)
150 : isLatin1(atom
->hasLatin1Chars()), length(atom
->length()), atom(atom
)
153 latin1Chars
= atom
->latin1Chars(nogc
);
154 hash
= mozilla::HashString(latin1Chars
, length
);
156 twoByteChars
= atom
->twoByteChars(nogc
);
157 hash
= mozilla::HashString(twoByteChars
, length
);
162 AtomHasher::match(const AtomStateEntry
& entry
, const Lookup
& lookup
)
164 JSAtom
* key
= entry
.asPtr();
166 return lookup
.atom
== key
;
167 if (key
->length() != lookup
.length
)
170 if (key
->hasLatin1Chars()) {
171 const Latin1Char
* keyChars
= key
->latin1Chars(lookup
.nogc
);
173 return mozilla::PodEqual(keyChars
, lookup
.latin1Chars
, lookup
.length
);
174 return EqualChars(keyChars
, lookup
.twoByteChars
, lookup
.length
);
177 const jschar
* keyChars
= key
->twoByteChars(lookup
.nogc
);
179 return EqualChars(lookup
.latin1Chars
, keyChars
, lookup
.length
);
180 return mozilla::PodEqual(keyChars
, lookup
.twoByteChars
, lookup
.length
);
183 inline Handle
<PropertyName
*>
184 TypeName(JSType type
, const JSAtomState
& names
)
186 JS_ASSERT(type
< JSTYPE_LIMIT
);
187 JS_STATIC_ASSERT(offsetof(JSAtomState
, undefined
) +
188 JSTYPE_LIMIT
* sizeof(ImmutablePropertyNamePtr
) <=
189 sizeof(JSAtomState
));
190 JS_STATIC_ASSERT(JSTYPE_VOID
== 0);
191 return (&names
.undefined
)[type
];
194 inline Handle
<PropertyName
*>
195 ClassName(JSProtoKey key
, JSAtomState
& atomState
)
197 JS_ASSERT(key
< JSProto_LIMIT
);
198 JS_STATIC_ASSERT(offsetof(JSAtomState
, Null
) +
199 JSProto_LIMIT
* sizeof(ImmutablePropertyNamePtr
) <=
200 sizeof(JSAtomState
));
201 JS_STATIC_ASSERT(JSProto_Null
== 0);
202 return (&atomState
.Null
)[key
];
205 inline Handle
<PropertyName
*>
206 ClassName(JSProtoKey key
, JSRuntime
* rt
)
208 return ClassName(key
, *rt
->commonNames
);
211 inline Handle
<PropertyName
*>
212 ClassName(JSProtoKey key
, ExclusiveContext
* cx
)
214 return ClassName(key
, cx
->names());
219 #endif /* jsatominlines_h */