diff -r 000000000000 -r 6474c204b198 js/src/jsatominlines.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/js/src/jsatominlines.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,192 @@ +/* -*- 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() const +{ + JS_ASSERT(bits != 0); + JSAtom *atom = reinterpret_cast(bits & NO_TAG_MASK); + JSString::readBarrier(atom); + return atom; +} + +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 (!v.isString() || !v.toString()->isAtom()) + return false; + + *id = AtomToId(&v.toString()->asAtom()); + return true; +} + +template +inline bool +ValueToId(JSContext* cx, typename MaybeRooted::HandleType v, + typename MaybeRooted::MutableHandleType idp) +{ + int32_t i; + if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) { + idp.set(INT_TO_JSID(i)); + return true; + } + + JSAtom *atom = ToAtom(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 +inline mozilla::RangedPtr +BackfillIndexInCharBuffer(uint32_t index, mozilla::RangedPtr 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(cx, JSID_TO_INT(id)); + + RootedValue idv(cx, IdToValue(id)); + JSString *str = ToStringSlow(cx, idv); + if (!str) + return nullptr; + + return str->ensureFlat(cx); +} + +inline +AtomHasher::Lookup::Lookup(const JSAtom *atom) + : chars(atom->chars()), length(atom->length()), atom(atom) +{ + hash = mozilla::HashString(chars, length); +} + +inline bool +AtomHasher::match(const AtomStateEntry &entry, const Lookup &lookup) +{ + JSAtom *key = entry.asPtr(); + if (lookup.atom) + return lookup.atom == key; + if (key->length() != lookup.length) + return false; + return mozilla::PodEqual(key->chars(), lookup.chars, lookup.length); +} + +inline Handle +TypeName(JSType type, const JSAtomState &names) +{ + JS_ASSERT(type < JSTYPE_LIMIT); + JS_STATIC_ASSERT(offsetof(JSAtomState, undefined) + + JSTYPE_LIMIT * sizeof(FixedHeapPtr) <= + sizeof(JSAtomState)); + JS_STATIC_ASSERT(JSTYPE_VOID == 0); + return (&names.undefined)[type]; +} + +inline Handle +ClassName(JSProtoKey key, JSAtomState &atomState) +{ + JS_ASSERT(key < JSProto_LIMIT); + JS_STATIC_ASSERT(offsetof(JSAtomState, Null) + + JSProto_LIMIT * sizeof(FixedHeapPtr) <= + sizeof(JSAtomState)); + JS_STATIC_ASSERT(JSProto_Null == 0); + return (&atomState.Null)[key]; +} + +inline Handle +ClassName(JSProtoKey key, JSRuntime *rt) +{ + return ClassName(key, *rt->commonNames); +} + +inline Handle +ClassName(JSProtoKey key, ExclusiveContext *cx) +{ + return ClassName(key, cx->names()); +} + +} // namespace js + +#endif /* jsatominlines_h */