V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
name.h
1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_OBJECTS_NAME_H_
6 #define V8_OBJECTS_NAME_H_
7 
8 #include "src/objects.h"
9 #include "src/objects/heap-object.h"
10 
11 // Has to be the last include (doesn't have include guards):
12 #include "src/objects/object-macros.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 // The Name abstract class captures anything that can be used as a property
18 // name, i.e., strings and symbols. All names store a hash value.
19 class Name : public HeapObjectPtr {
20  public:
21  // Get and set the hash field of the name.
22  inline uint32_t hash_field();
23  inline void set_hash_field(uint32_t value);
24 
25  // Tells whether the hash code has been computed.
26  inline bool HasHashCode();
27 
28  // Returns a hash value used for the property table
29  inline uint32_t Hash();
30 
31  // Equality operations.
32  inline bool Equals(Name other);
33  inline static bool Equals(Isolate* isolate, Handle<Name> one,
34  Handle<Name> two);
35 
36  // Conversion.
37  inline bool AsArrayIndex(uint32_t* index);
38 
39  // An "interesting symbol" is a well-known symbol, like @@toStringTag,
40  // that's often looked up on random objects but is usually not present.
41  // We optimize this by setting a flag on the object's map when such
42  // symbol properties are added, so we can optimize lookups on objects
43  // that don't have the flag.
44  inline bool IsInterestingSymbol() const;
45 
46  // If the name is private, it can only name own properties.
47  inline bool IsPrivate();
48 
49  // If the name is a private name, it should behave like a private
50  // symbol but also throw on property access miss.
51  inline bool IsPrivateName();
52 
53  inline bool IsUniqueName() const;
54 
55  static inline bool ContainsCachedArrayIndex(uint32_t hash);
56 
57  // Return a string version of this name that is converted according to the
58  // rules described in ES6 section 9.2.11.
59  V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToFunctionName(
60  Isolate* isolate, Handle<Name> name);
61  V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToFunctionName(
62  Isolate* isolate, Handle<Name> name, Handle<String> prefix);
63 
64  DECL_CAST2(Name)
65 
66  DECL_PRINTER(Name)
67  void NameShortPrint();
68  int NameShortPrint(Vector<char> str);
69 
70  // Layout description.
71  static const int kHashFieldOffset = HeapObject::kHeaderSize;
72  static const int kHeaderSize = kHashFieldOffset + kInt32Size;
73 
74  // Mask constant for checking if a name has a computed hash code
75  // and if it is a string that is an array index. The least significant bit
76  // indicates whether a hash code has been computed. If the hash code has
77  // been computed the 2nd bit tells whether the string can be used as an
78  // array index.
79  static const int kHashNotComputedMask = 1;
80  static const int kIsNotArrayIndexMask = 1 << 1;
81  static const int kNofHashBitFields = 2;
82 
83  // Shift constant retrieving hash code from hash field.
84  static const int kHashShift = kNofHashBitFields;
85 
86  // Only these bits are relevant in the hash, since the top two are shifted
87  // out.
88  static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
89 
90  // Array index strings this short can keep their index in the hash field.
91  static const int kMaxCachedArrayIndexLength = 7;
92 
93  // Maximum number of characters to consider when trying to convert a string
94  // value into an array index.
95  static const int kMaxArrayIndexSize = 10;
96 
97  // For strings which are array indexes the hash value has the string length
98  // mixed into the hash, mainly to avoid a hash value of zero which would be
99  // the case for the string '0'. 24 bits are used for the array index value.
100  static const int kArrayIndexValueBits = 24;
101  static const int kArrayIndexLengthBits =
102  kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
103 
104  STATIC_ASSERT(kArrayIndexLengthBits > 0);
105  STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
106 
108  : public BitField<unsigned int, kNofHashBitFields, kArrayIndexValueBits> {
109  }; // NOLINT
111  : public BitField<unsigned int, kNofHashBitFields + kArrayIndexValueBits,
112  kArrayIndexLengthBits> {}; // NOLINT
113 
114  // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
115  // could use a mask to test if the length of string is less than or equal to
116  // kMaxCachedArrayIndexLength.
117  static_assert(base::bits::IsPowerOfTwo(kMaxCachedArrayIndexLength + 1),
118  "(kMaxCachedArrayIndexLength + 1) must be power of two");
119 
120  // When any of these bits is set then the hash field does not contain a cached
121  // array index.
122  static const unsigned int kDoesNotContainCachedArrayIndexMask =
123  (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
124  << ArrayIndexLengthBits::kShift) |
125  kIsNotArrayIndexMask;
126 
127  // Value of empty hash field indicating that the hash is not computed.
128  static const int kEmptyHashField =
129  kIsNotArrayIndexMask | kHashNotComputedMask;
130 
131  protected:
132  static inline bool IsHashFieldComputed(uint32_t field);
133 
134  OBJECT_CONSTRUCTORS(Name, HeapObjectPtr);
135 };
136 
137 // ES6 symbols.
138 class Symbol : public Name {
139  public:
140  // [name]: The print name of a symbol, or undefined if none.
141  DECL_ACCESSORS(name, Object)
142 
143  DECL_INT_ACCESSORS(flags)
144 
145  // [is_private]: Whether this is a private symbol. Private symbols can only
146  // be used to designate own properties of objects.
147  DECL_BOOLEAN_ACCESSORS(is_private)
148 
149  // [is_well_known_symbol]: Whether this is a spec-defined well-known symbol,
150  // or not. Well-known symbols do not throw when an access check fails during
151  // a load.
152  DECL_BOOLEAN_ACCESSORS(is_well_known_symbol)
153 
154  // [is_interesting_symbol]: Whether this is an "interesting symbol", which
155  // is a well-known symbol like @@toStringTag that's often looked up on
156  // random objects but is usually not present. See Name::IsInterestingSymbol()
157  // for a detailed description.
158  DECL_BOOLEAN_ACCESSORS(is_interesting_symbol)
159 
160  // [is_public]: Whether this is a symbol created by Symbol.for. Calling
161  // Symbol.keyFor on such a symbol simply needs to return the attached name.
162  DECL_BOOLEAN_ACCESSORS(is_public)
163 
164  // [is_private_name]: Whether this is a private name. Private names
165  // are the same as private symbols except they throw on missing
166  // property access.
167  //
168  // This also sets the is_private bit.
169  inline bool is_private_name() const;
170  inline void set_is_private_name();
171 
172  DECL_CAST2(Symbol)
173 
174  // Dispatched behavior.
175  DECL_PRINTER(Symbol)
176  DECL_VERIFIER(Symbol)
177 
178  // Layout description.
179 #define SYMBOL_FIELDS(V) \
180  V(kFlagsOffset, kInt32Size) \
181  V(kNameOffset, kTaggedSize) \
182  /* Header size. */ \
183  V(kSize, 0)
184 
185  DEFINE_FIELD_OFFSET_CONSTANTS(Name::kHeaderSize, SYMBOL_FIELDS)
186 #undef SYMBOL_FIELDS
187 
188 // Flags layout.
189 #define FLAGS_BIT_FIELDS(V, _) \
190  V(IsPrivateBit, bool, 1, _) \
191  V(IsWellKnownSymbolBit, bool, 1, _) \
192  V(IsPublicBit, bool, 1, _) \
193  V(IsInterestingSymbolBit, bool, 1, _) \
194  V(IsPrivateNameBit, bool, 1, _)
195 
196  DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
197 #undef FLAGS_BIT_FIELDS
198 
200 
201  void SymbolShortPrint(std::ostream& os);
202 
203  private:
204  const char* PrivateSymbolToName() const;
205 
206  // TODO(cbruni): remove once the new maptracer is in place.
207  friend class Name; // For PrivateSymbolToName.
208 
209  OBJECT_CONSTRUCTORS(Symbol, Name);
210 };
211 
212 } // namespace internal
213 } // namespace v8
214 
215 #include "src/objects/object-macros-undef.h"
216 
217 #endif // V8_OBJECTS_NAME_H_
Definition: libplatform.h:13