1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsatominlines.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,192 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef jsatominlines_h 1.11 +#define jsatominlines_h 1.12 + 1.13 +#include "jsatom.h" 1.14 + 1.15 +#include "mozilla/PodOperations.h" 1.16 +#include "mozilla/RangedPtr.h" 1.17 + 1.18 +#include "jscntxt.h" 1.19 +#include "jsnum.h" 1.20 + 1.21 +#include "vm/String.h" 1.22 + 1.23 +inline JSAtom * 1.24 +js::AtomStateEntry::asPtr() const 1.25 +{ 1.26 + JS_ASSERT(bits != 0); 1.27 + JSAtom *atom = reinterpret_cast<JSAtom *>(bits & NO_TAG_MASK); 1.28 + JSString::readBarrier(atom); 1.29 + return atom; 1.30 +} 1.31 + 1.32 +namespace js { 1.33 + 1.34 +inline jsid 1.35 +AtomToId(JSAtom *atom) 1.36 +{ 1.37 + JS_STATIC_ASSERT(JSID_INT_MIN == 0); 1.38 + 1.39 + uint32_t index; 1.40 + if (atom->isIndex(&index) && index <= JSID_INT_MAX) 1.41 + return INT_TO_JSID(int32_t(index)); 1.42 + 1.43 + return JSID_FROM_BITS(size_t(atom)); 1.44 +} 1.45 + 1.46 +inline bool 1.47 +ValueToIdPure(const Value &v, jsid *id) 1.48 +{ 1.49 + int32_t i; 1.50 + if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) { 1.51 + *id = INT_TO_JSID(i); 1.52 + return true; 1.53 + } 1.54 + 1.55 + if (!v.isString() || !v.toString()->isAtom()) 1.56 + return false; 1.57 + 1.58 + *id = AtomToId(&v.toString()->asAtom()); 1.59 + return true; 1.60 +} 1.61 + 1.62 +template <AllowGC allowGC> 1.63 +inline bool 1.64 +ValueToId(JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType v, 1.65 + typename MaybeRooted<jsid, allowGC>::MutableHandleType idp) 1.66 +{ 1.67 + int32_t i; 1.68 + if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) { 1.69 + idp.set(INT_TO_JSID(i)); 1.70 + return true; 1.71 + } 1.72 + 1.73 + JSAtom *atom = ToAtom<allowGC>(cx, v); 1.74 + if (!atom) 1.75 + return false; 1.76 + 1.77 + idp.set(AtomToId(atom)); 1.78 + return true; 1.79 +} 1.80 + 1.81 +/* 1.82 + * Write out character representing |index| to the memory just before |end|. 1.83 + * Thus |*end| is not touched, but |end[-1]| and earlier are modified as 1.84 + * appropriate. There must be at least js::UINT32_CHAR_BUFFER_LENGTH elements 1.85 + * before |end| to avoid buffer underflow. The start of the characters written 1.86 + * is returned and is necessarily before |end|. 1.87 + */ 1.88 +template <typename T> 1.89 +inline mozilla::RangedPtr<T> 1.90 +BackfillIndexInCharBuffer(uint32_t index, mozilla::RangedPtr<T> end) 1.91 +{ 1.92 +#ifdef DEBUG 1.93 + /* 1.94 + * Assert that the buffer we're filling will hold as many characters as we 1.95 + * could write out, by dereferencing the index that would hold the most 1.96 + * significant digit. 1.97 + */ 1.98 + (void) *(end - UINT32_CHAR_BUFFER_LENGTH); 1.99 +#endif 1.100 + 1.101 + do { 1.102 + uint32_t next = index / 10, digit = index % 10; 1.103 + *--end = '0' + digit; 1.104 + index = next; 1.105 + } while (index > 0); 1.106 + 1.107 + return end; 1.108 +} 1.109 + 1.110 +bool 1.111 +IndexToIdSlow(ExclusiveContext *cx, uint32_t index, MutableHandleId idp); 1.112 + 1.113 +inline bool 1.114 +IndexToId(ExclusiveContext *cx, uint32_t index, MutableHandleId idp) 1.115 +{ 1.116 + if (index <= JSID_INT_MAX) { 1.117 + idp.set(INT_TO_JSID(index)); 1.118 + return true; 1.119 + } 1.120 + 1.121 + return IndexToIdSlow(cx, index, idp); 1.122 +} 1.123 + 1.124 +static MOZ_ALWAYS_INLINE JSFlatString * 1.125 +IdToString(JSContext *cx, jsid id) 1.126 +{ 1.127 + if (JSID_IS_STRING(id)) 1.128 + return JSID_TO_ATOM(id); 1.129 + 1.130 + if (MOZ_LIKELY(JSID_IS_INT(id))) 1.131 + return Int32ToString<CanGC>(cx, JSID_TO_INT(id)); 1.132 + 1.133 + RootedValue idv(cx, IdToValue(id)); 1.134 + JSString *str = ToStringSlow<CanGC>(cx, idv); 1.135 + if (!str) 1.136 + return nullptr; 1.137 + 1.138 + return str->ensureFlat(cx); 1.139 +} 1.140 + 1.141 +inline 1.142 +AtomHasher::Lookup::Lookup(const JSAtom *atom) 1.143 + : chars(atom->chars()), length(atom->length()), atom(atom) 1.144 +{ 1.145 + hash = mozilla::HashString(chars, length); 1.146 +} 1.147 + 1.148 +inline bool 1.149 +AtomHasher::match(const AtomStateEntry &entry, const Lookup &lookup) 1.150 +{ 1.151 + JSAtom *key = entry.asPtr(); 1.152 + if (lookup.atom) 1.153 + return lookup.atom == key; 1.154 + if (key->length() != lookup.length) 1.155 + return false; 1.156 + return mozilla::PodEqual(key->chars(), lookup.chars, lookup.length); 1.157 +} 1.158 + 1.159 +inline Handle<PropertyName*> 1.160 +TypeName(JSType type, const JSAtomState &names) 1.161 +{ 1.162 + JS_ASSERT(type < JSTYPE_LIMIT); 1.163 + JS_STATIC_ASSERT(offsetof(JSAtomState, undefined) + 1.164 + JSTYPE_LIMIT * sizeof(FixedHeapPtr<PropertyName>) <= 1.165 + sizeof(JSAtomState)); 1.166 + JS_STATIC_ASSERT(JSTYPE_VOID == 0); 1.167 + return (&names.undefined)[type]; 1.168 +} 1.169 + 1.170 +inline Handle<PropertyName*> 1.171 +ClassName(JSProtoKey key, JSAtomState &atomState) 1.172 +{ 1.173 + JS_ASSERT(key < JSProto_LIMIT); 1.174 + JS_STATIC_ASSERT(offsetof(JSAtomState, Null) + 1.175 + JSProto_LIMIT * sizeof(FixedHeapPtr<PropertyName>) <= 1.176 + sizeof(JSAtomState)); 1.177 + JS_STATIC_ASSERT(JSProto_Null == 0); 1.178 + return (&atomState.Null)[key]; 1.179 +} 1.180 + 1.181 +inline Handle<PropertyName*> 1.182 +ClassName(JSProtoKey key, JSRuntime *rt) 1.183 +{ 1.184 + return ClassName(key, *rt->commonNames); 1.185 +} 1.186 + 1.187 +inline Handle<PropertyName*> 1.188 +ClassName(JSProtoKey key, ExclusiveContext *cx) 1.189 +{ 1.190 + return ClassName(key, cx->names()); 1.191 +} 1.192 + 1.193 +} // namespace js 1.194 + 1.195 +#endif /* jsatominlines_h */