String.h (3648B)
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 /* Shadow definition of |JSString| innards. Don't use this directly! */ 8 9 #ifndef js_shadow_String_h 10 #define js_shadow_String_h 11 12 #include <stdint.h> // uint32_t, uintptr_t 13 14 #include "jstypes.h" // JS_PUBLIC_API, js::Bit, js::BitMask, JS_BITS_PER_WORD 15 16 #include "js/TypeDecls.h" // JS::Latin1Char 17 18 class JS_PUBLIC_API JSAtom; 19 struct JSExternalStringCallbacks; 20 class JSLinearString; 21 class JS_PUBLIC_API JSString; 22 23 namespace js { 24 namespace gc { 25 struct Cell; 26 } // namespace gc 27 } // namespace js 28 29 namespace JS { 30 31 namespace shadow { 32 33 struct String { 34 static constexpr uint32_t ATOM_BIT = js::Bit(3); 35 static constexpr uint32_t LINEAR_BIT = js::Bit(4); 36 static constexpr uint32_t INLINE_CHARS_BIT = js::Bit(6); 37 static constexpr uint32_t LATIN1_CHARS_BIT = js::Bit(10); 38 static constexpr uint32_t HAS_STRING_BUFFER_BIT = js::Bit(12); 39 static constexpr uint32_t EXTERNAL_FLAGS = LINEAR_BIT | js::Bit(8); 40 static constexpr uint32_t TYPE_FLAGS_MASK = js::BitMask(10) - js::BitMask(3); 41 static constexpr uint32_t PERMANENT_ATOM_MASK = ATOM_BIT | js::Bit(8); 42 43 uintptr_t flags_; 44 #if JS_BITS_PER_WORD == 32 45 uint32_t length_; 46 #endif 47 48 union { 49 const JS::Latin1Char* nonInlineCharsLatin1; 50 const char16_t* nonInlineCharsTwoByte; 51 JS::Latin1Char inlineStorageLatin1[1]; 52 char16_t inlineStorageTwoByte[1]; 53 }; 54 const JSExternalStringCallbacks* externalCallbacks; 55 56 uint32_t flags() const { return static_cast<uint32_t>(flags_); } 57 uint32_t length() const { 58 #if JS_BITS_PER_WORD == 32 59 return length_; 60 #else 61 return static_cast<uint32_t>(flags_ >> 32); 62 #endif 63 } 64 65 static bool isPermanentAtom(const js::gc::Cell* cell) { 66 uint32_t flags = reinterpret_cast<const String*>(cell)->flags(); 67 return (flags & PERMANENT_ATOM_MASK) == PERMANENT_ATOM_MASK; 68 } 69 70 bool isLinear() const { return flags() & LINEAR_BIT; } 71 bool hasLatin1Chars() const { return flags() & LATIN1_CHARS_BIT; } 72 bool hasStringBuffer() const { return flags() & HAS_STRING_BUFFER_BIT; } 73 74 // For hot code, prefer other type queries. 75 bool isExternal() const { 76 return (flags() & TYPE_FLAGS_MASK) == EXTERNAL_FLAGS; 77 } 78 79 const JS::Latin1Char* latin1LinearChars() const { 80 MOZ_ASSERT(isLinear()); 81 MOZ_ASSERT(hasLatin1Chars()); 82 return (flags() & String::INLINE_CHARS_BIT) ? inlineStorageLatin1 83 : nonInlineCharsLatin1; 84 } 85 86 const char16_t* twoByteLinearChars() const { 87 MOZ_ASSERT(isLinear()); 88 MOZ_ASSERT(!hasLatin1Chars()); 89 return (flags() & String::INLINE_CHARS_BIT) ? inlineStorageTwoByte 90 : nonInlineCharsTwoByte; 91 } 92 }; 93 94 inline const String* AsShadowString(const JSString* str) { 95 return reinterpret_cast<const String*>(str); 96 } 97 98 inline String* AsShadowString(JSString* str) { 99 return reinterpret_cast<String*>(str); 100 } 101 102 inline const String* AsShadowString(const JSLinearString* str) { 103 return reinterpret_cast<const String*>(str); 104 } 105 106 inline String* AsShadowString(JSLinearString* str) { 107 return reinterpret_cast<String*>(str); 108 } 109 110 inline const String* AsShadowString(const JSAtom* str) { 111 return reinterpret_cast<const String*>(str); 112 } 113 114 inline String* AsShadowString(JSAtom* str) { 115 return reinterpret_cast<String*>(str); 116 } 117 118 } // namespace shadow 119 120 } // namespace JS 121 122 #endif // js_shadow_String_h