diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /js/src/jsatominlines.h | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | uxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz |
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/jsatominlines.h')
-rw-r--r-- | js/src/jsatominlines.h | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/js/src/jsatominlines.h b/js/src/jsatominlines.h new file mode 100644 index 0000000000..d7517e4cbf --- /dev/null +++ b/js/src/jsatominlines.h @@ -0,0 +1,221 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef jsatominlines_h +#define jsatominlines_h + +#include "jsatom.h" + +#include "mozilla/PodOperations.h" +#include "mozilla/RangedPtr.h" + +#include "jscntxt.h" +#include "jsnum.h" + +#include "vm/String.h" + +inline JSAtom* +js::AtomStateEntry::asPtr(js::ExclusiveContext* cx) const +{ + JSAtom* atom = asPtrUnbarriered(); + if (cx->isJSContext()) + JSString::readBarrier(atom); + return atom; +} + +inline JSAtom* +js::AtomStateEntry::asPtrUnbarriered() const +{ + MOZ_ASSERT(bits != 0); + return reinterpret_cast<JSAtom*>(bits & NO_TAG_MASK); +} + +namespace js { + +inline jsid +AtomToId(JSAtom* atom) +{ + JS_STATIC_ASSERT(JSID_INT_MIN == 0); + + uint32_t index; + if (atom->isIndex(&index) && index <= JSID_INT_MAX) + return INT_TO_JSID(int32_t(index)); + + return JSID_FROM_BITS(size_t(atom)); +} + +inline bool +ValueToIdPure(const Value& v, jsid* id) +{ + int32_t i; + if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) { + *id = INT_TO_JSID(i); + return true; + } + + if (js::IsSymbolOrSymbolWrapper(v)) { + *id = SYMBOL_TO_JSID(js::ToSymbolPrimitive(v)); + return true; + } + + if (!v.isString() || !v.toString()->isAtom()) + return false; + + *id = AtomToId(&v.toString()->asAtom()); + return true; +} + +template <AllowGC allowGC> +inline bool +ValueToId(ExclusiveContext* cx, typename MaybeRooted<Value, allowGC>::HandleType v, + typename MaybeRooted<jsid, allowGC>::MutableHandleType idp) +{ + int32_t i; + if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) { + idp.set(INT_TO_JSID(i)); + return true; + } + + if (js::IsSymbolOrSymbolWrapper(v)) { + idp.set(SYMBOL_TO_JSID(js::ToSymbolPrimitive(v))); + return true; + } + + JSAtom* atom = ToAtom<allowGC>(cx, v); + if (!atom) + return false; + + idp.set(AtomToId(atom)); + return true; +} + +/* + * Write out character representing |index| to the memory just before |end|. + * Thus |*end| is not touched, but |end[-1]| and earlier are modified as + * appropriate. There must be at least js::UINT32_CHAR_BUFFER_LENGTH elements + * before |end| to avoid buffer underflow. The start of the characters written + * is returned and is necessarily before |end|. + */ +template <typename T> +inline mozilla::RangedPtr<T> +BackfillIndexInCharBuffer(uint32_t index, mozilla::RangedPtr<T> end) +{ +#ifdef DEBUG + /* + * Assert that the buffer we're filling will hold as many characters as we + * could write out, by dereferencing the index that would hold the most + * significant digit. + */ + (void) *(end - UINT32_CHAR_BUFFER_LENGTH); +#endif + + do { + uint32_t next = index / 10, digit = index % 10; + *--end = '0' + digit; + index = next; + } while (index > 0); + + return end; +} + +bool +IndexToIdSlow(ExclusiveContext* cx, uint32_t index, MutableHandleId idp); + +inline bool +IndexToId(ExclusiveContext* cx, uint32_t index, MutableHandleId idp) +{ + if (index <= JSID_INT_MAX) { + idp.set(INT_TO_JSID(index)); + return true; + } + + return IndexToIdSlow(cx, index, idp); +} + +static MOZ_ALWAYS_INLINE JSFlatString* +IdToString(JSContext* cx, jsid id) +{ + if (JSID_IS_STRING(id)) + return JSID_TO_ATOM(id); + + if (MOZ_LIKELY(JSID_IS_INT(id))) + return Int32ToString<CanGC>(cx, JSID_TO_INT(id)); + + RootedValue idv(cx, IdToValue(id)); + JSString* str = ToStringSlow<CanGC>(cx, idv); + if (!str) + return nullptr; + + return str->ensureFlat(cx); +} + +inline +AtomHasher::Lookup::Lookup(const JSAtom* atom) + : isLatin1(atom->hasLatin1Chars()), length(atom->length()), atom(atom) +{ + hash = atom->hash(); + if (isLatin1) { + latin1Chars = atom->latin1Chars(nogc); + MOZ_ASSERT(mozilla::HashString(latin1Chars, length) == hash); + } else { + twoByteChars = atom->twoByteChars(nogc); + MOZ_ASSERT(mozilla::HashString(twoByteChars, length) == hash); + } +} + +inline bool +AtomHasher::match(const AtomStateEntry& entry, const Lookup& lookup) +{ + JSAtom* key = entry.asPtrUnbarriered(); + if (lookup.atom) + return lookup.atom == key; + if (key->length() != lookup.length || key->hash() != lookup.hash) + return false; + + if (key->hasLatin1Chars()) { + const Latin1Char* keyChars = key->latin1Chars(lookup.nogc); + if (lookup.isLatin1) + return mozilla::PodEqual(keyChars, lookup.latin1Chars, lookup.length); + return EqualChars(keyChars, lookup.twoByteChars, lookup.length); + } + + const char16_t* keyChars = key->twoByteChars(lookup.nogc); + if (lookup.isLatin1) + return EqualChars(lookup.latin1Chars, keyChars, lookup.length); + return mozilla::PodEqual(keyChars, lookup.twoByteChars, lookup.length); +} + +inline Handle<PropertyName*> +TypeName(JSType type, const JSAtomState& names) +{ + MOZ_ASSERT(type < JSTYPE_LIMIT); + JS_STATIC_ASSERT(offsetof(JSAtomState, undefined) + + JSTYPE_LIMIT * sizeof(ImmutablePropertyNamePtr) <= + sizeof(JSAtomState)); + JS_STATIC_ASSERT(JSTYPE_VOID == 0); + return (&names.undefined)[type]; +} + +inline Handle<PropertyName*> +ClassName(JSProtoKey key, JSAtomState& atomState) +{ + MOZ_ASSERT(key < JSProto_LIMIT); + JS_STATIC_ASSERT(offsetof(JSAtomState, Null) + + JSProto_LIMIT * sizeof(ImmutablePropertyNamePtr) <= + sizeof(JSAtomState)); + JS_STATIC_ASSERT(JSProto_Null == 0); + return (&atomState.Null)[key]; +} + +inline Handle<PropertyName*> +ClassName(JSProtoKey key, ExclusiveContext* cx) +{ + return ClassName(key, cx->names()); +} + +} // namespace js + +#endif /* jsatominlines_h */ |