JSAtomUtils-inl.h (3821B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 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/. */ 6 7 #ifndef vm_JSAtomUtils_inl_h 8 #define vm_JSAtomUtils_inl_h 9 10 #include "vm/JSAtomUtils.h" 11 12 #include "jsnum.h" 13 14 #include "gc/MaybeRooted.h" 15 #include "vm/JSAtomState.h" 16 #include "vm/JSContext.h" 17 #include "vm/StringType.h" 18 19 namespace js { 20 21 MOZ_ALWAYS_INLINE jsid AtomToId(JSAtom* atom) { 22 static_assert(JS::PropertyKey::IntMin == 0); 23 24 uint32_t index; 25 if (atom->isIndex(&index) && index <= JS::PropertyKey::IntMax) { 26 return JS::PropertyKey::Int(int32_t(index)); 27 } 28 29 return JS::PropertyKey::NonIntAtom(atom); 30 } 31 32 // Use the NameToId method instead! 33 inline jsid AtomToId(PropertyName* name) = delete; 34 35 template <AllowGC allowGC> 36 extern bool PrimitiveValueToIdSlow( 37 JSContext* cx, typename MaybeRooted<JS::Value, allowGC>::HandleType v, 38 typename MaybeRooted<jsid, allowGC>::MutableHandleType idp); 39 40 template <AllowGC allowGC> 41 inline bool PrimitiveValueToId( 42 JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType v, 43 typename MaybeRooted<jsid, allowGC>::MutableHandleType idp) { 44 // Non-primitive values should call ToPropertyKey. 45 MOZ_ASSERT(v.isPrimitive()); 46 47 if (v.isString()) { 48 JSAtom* atom = AtomizeString(cx, v.toString()); 49 if (!atom) { 50 if constexpr (!allowGC) { 51 cx->recoverFromOutOfMemory(); 52 } 53 return false; 54 } 55 idp.set(AtomToId(atom)); 56 return true; 57 } 58 59 if (v.isInt32()) { 60 if (PropertyKey::fitsInInt(v.toInt32())) { 61 idp.set(PropertyKey::Int(v.toInt32())); 62 return true; 63 } 64 } else if (v.isSymbol()) { 65 idp.set(PropertyKey::Symbol(v.toSymbol())); 66 return true; 67 } 68 69 return PrimitiveValueToIdSlow<allowGC>(cx, v, idp); 70 } 71 72 bool IndexToIdSlow(JSContext* cx, uint32_t index, MutableHandleId idp); 73 74 inline bool IndexToId(JSContext* cx, uint32_t index, MutableHandleId idp) { 75 if (index <= PropertyKey::IntMax) { 76 idp.set(PropertyKey::Int(index)); 77 return true; 78 } 79 80 return IndexToIdSlow(cx, index, idp); 81 } 82 83 bool IndexToIdSlow(JSContext* cx, uint64_t index, MutableHandleId idp); 84 85 inline bool IndexToId(JSContext* cx, uint64_t index, MutableHandleId idp) { 86 MOZ_ASSERT(index < uint64_t(DOUBLE_INTEGRAL_PRECISION_LIMIT)); 87 88 if (index <= PropertyKey::IntMax) { 89 idp.set(PropertyKey::Int(index)); 90 return true; 91 } 92 93 return IndexToIdSlow(cx, index, idp); 94 } 95 96 static MOZ_ALWAYS_INLINE JSLinearString* IdToString( 97 JSContext* cx, jsid id, gc::Heap heap = gc::Heap::Default) { 98 if (id.isString()) { 99 return id.toAtom(); 100 } 101 102 if (MOZ_LIKELY(id.isInt())) { 103 return Int32ToStringWithHeap<CanGC>(cx, id.toInt(), heap); 104 } 105 106 RootedValue idv(cx, IdToValue(id)); 107 JSString* str = ToStringSlow<CanGC>(cx, idv); 108 if (!str) { 109 return nullptr; 110 } 111 112 return str->ensureLinear(cx); 113 } 114 115 inline Handle<PropertyName*> TypeName(JSType type, const JSAtomState& names) { 116 MOZ_ASSERT(type < JSTYPE_LIMIT); 117 static_assert(offsetof(JSAtomState, undefined) + 118 JSTYPE_LIMIT * sizeof(ImmutableTenuredPtr<PropertyName*>) <= 119 sizeof(JSAtomState)); 120 static_assert(JSTYPE_UNDEFINED == 0); 121 return (&names.undefined)[type]; 122 } 123 124 inline Handle<PropertyName*> ClassName(JSProtoKey key, JSAtomState& atomState) { 125 MOZ_ASSERT(key < JSProto_LIMIT); 126 static_assert(offsetof(JSAtomState, Null) + 127 JSProto_LIMIT * 128 sizeof(ImmutableTenuredPtr<PropertyName*>) <= 129 sizeof(JSAtomState)); 130 static_assert(JSProto_Null == 0); 131 return (&atomState.Null)[key]; 132 } 133 134 } // namespace js 135 136 #endif /* vm_JSAtomUtils_inl_h */