v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
keys.h
Go to the documentation of this file.
1// Copyright 2012 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_KEYS_H_
6#define V8_OBJECTS_KEYS_H_
7
8#include "include/v8-object.h"
11#include "src/objects/objects.h"
12
13namespace v8 {
14namespace internal {
15
16class AccessCheckInfo;
17class FastKeyAccumulator;
18class JSProxy;
19
21
27
33
34// This is a helper class for JSReceiver::GetKeys which collects and sorts keys.
35// GetKeys needs to sort keys per prototype level, first showing the integer
36// indices from elements then the strings from the properties. However, this
37// does not apply to proxies which are in full control of how the keys are
38// sorted.
39//
40// For performance reasons the KeyAccumulator internally separates integer keys
41// in |elements_| into sorted lists per prototype level. String keys are
42// collected in |string_properties_|, a single OrderedHashSet (similar for
43// Symbols in |symbol_properties_|. To separate the keys per level later when
44// assembling the final list, |levelLengths_| keeps track of the number of
45// String and Symbol keys per level.
46//
47// Only unique keys are kept by the KeyAccumulator, strings are stored in a
48// HashSet for inexpensive lookups. Integer keys are kept in sorted lists which
49// are more compact and allow for reasonably fast includes check.
50class KeyAccumulator final {
51 public:
53 PropertyFilter filter)
54 : isolate_(isolate), mode_(mode), filter_(filter) {}
55 ~KeyAccumulator() = default;
58
61 PropertyFilter filter,
63 bool is_for_in = false, bool skip_indices = false);
64
69
70 // Might return directly the object's enum_cache, copy the result before using
71 // as an elements backing store for a JSObject.
72 // Does not throw for uninitialized exports in module namespace objects, so
73 // this has to be checked separately.
75 Isolate* isolate, DirectHandle<JSObject> object);
76
81
82 // Jump to the next level, pushing the current |levelLength_| to
83 // |levelLengths_| and adding a new list to |elements_|.
84 Isolate* isolate() { return isolate_; }
85 // Filter keys based on their property descriptors.
87 // The collection mode defines whether we collect the keys from the prototype
88 // chain or only look at the receiver.
90 void set_skip_indices(bool value) { skip_indices_ = value; }
91 // Shadowing keys are used to filter keys. This happens when non-enumerable
92 // keys appear again on the prototype chain.
95
96 private:
98
102 DirectHandle<AccessCheckInfo> access_check_info,
104
110 IndexedOrNamed type);
111
122
126 IndexedOrNamed type);
127
131 AddKeyConversion convert);
134
136 bool HasShadowingKeys();
138
139 // In case of for-in loops we have to treat JSProxy keys differently and
140 // deduplicate them. Additionally we convert JSProxy keys back to array
141 // indices.
142 void set_is_for_in(bool value) { is_for_in_ = value; }
150 // The last_non_empty_prototype is used to limit the prototypes for which
151 // we have to keep track of non-enumerable keys that can shadow keys
152 // repeated on the prototype chain.
157
166 bool is_for_in_ = false;
167 bool skip_indices_ = false;
168 // For all the keys on the first receiver adding a shadowing key we can skip
169 // the shadow check.
173
175};
176
177// The FastKeyAccumulator handles the cases where there are no elements on the
178// prototype chain and forwards the complex/slow cases to the normal
179// KeyAccumulator. This significantly speeds up the cases where the OWN_ONLY
180// case where we do not have to walk the prototype chain.
182 public:
185 bool is_for_in = false, bool skip_indices = false)
186 : isolate_(isolate),
188 mode_(mode),
189 filter_(filter),
190 is_for_in_(is_for_in),
191 skip_indices_(skip_indices) {
192 Prepare();
193 }
196
200
203
204 // Initialize the the enum cache for a map with all of the following:
205 // - uninitialized enum length
206 // - fast properties (i.e. !is_dictionary_map())
207 // - has >0 enumerable own properties
208 //
209 // The number of enumerable properties is passed in as an optimization, for
210 // when the caller has already computed it.
211 //
212 // Returns the keys.
214 Isolate* isolate, DirectHandle<Map> map, int enum_length,
216
217 private:
218 void Prepare();
222 GetKeysConversion convert);
223
225
228
236 bool is_for_in_ = false;
237 bool skip_indices_ = false;
244};
245
246} // namespace internal
247} // namespace v8
248
249#endif // V8_OBJECTS_KEYS_H_
FastKeyAccumulator & operator=(const FastKeyAccumulator &)=delete
static Handle< FixedArray > InitializeFastPropertyEnumCache(Isolate *isolate, DirectHandle< Map > map, int enum_length, AllocationType allocation=AllocationType::kOld)
Definition keys.cc:513
MaybeHandle< FixedArray > GetKeys(GetKeysConversion convert=GetKeysConversion::kKeepNumbers)
Definition keys.cc:454
MaybeHandle< FixedArray > GetKeysFast(GetKeysConversion convert)
Definition keys.cc:475
MaybeHandle< FixedArray > GetOwnKeysWithUninitializedEnumLength()
Definition keys.cc:576
FastKeyAccumulator(const FastKeyAccumulator &)=delete
MaybeHandle< FixedArray > GetKeysSlow(GetKeysConversion convert)
Definition keys.cc:599
bool TryPrototypeInfoCache(DirectHandle< JSReceiver > receiver)
Definition keys.cc:669
DirectHandle< Map > first_prototype_map_
Definition keys.h:231
DirectHandle< JSReceiver > receiver_
Definition keys.h:230
DirectHandle< JSReceiver > last_non_empty_prototype_
Definition keys.h:233
DirectHandle< JSReceiver > first_prototype_
Definition keys.h:232
bool MayHaveElements(Tagged< JSReceiver > receiver)
Definition keys.cc:661
MaybeHandle< FixedArray > GetKeysWithPrototypeInfoCache(GetKeysConversion convert)
Definition keys.cc:614
FastKeyAccumulator(Isolate *isolate, DirectHandle< JSReceiver > receiver, KeyCollectionMode mode, PropertyFilter filter, bool is_for_in=false, bool skip_indices=false)
Definition keys.h:183
KeyCollectionMode mode_
Definition keys.h:234
Maybe< bool > CollectOwnPropertyNames(DirectHandle< JSReceiver > receiver, DirectHandle< JSObject > object)
Definition keys.cc:1011
V8_WARN_UNUSED_RESULT ExceptionStatus CollectPrivateNames(DirectHandle< JSReceiver > receiver, DirectHandle< JSObject > object)
Definition keys.cc:1089
V8_WARN_UNUSED_RESULT ExceptionStatus FilterForEnumerableProperties(DirectHandle< JSReceiver > receiver, DirectHandle< JSObject > object, DirectHandle< InterceptorInfo > interceptor, DirectHandle< JSObject > result, IndexedOrNamed type)
Definition keys.cc:696
Maybe< bool > CollectKeys(DirectHandle< JSReceiver > receiver, DirectHandle< JSReceiver > object)
Definition keys.cc:250
KeyAccumulator(const KeyAccumulator &)=delete
Maybe< bool > CollectOwnJSProxyTargetKeys(DirectHandle< JSProxy > proxy, DirectHandle< JSReceiver > target)
Definition keys.cc:1392
void AddShadowingKey(Tagged< Object > key, AllowGarbageCollection *allow_gc)
Definition keys.cc:308
void set_may_have_elements(bool value)
Definition keys.h:156
Handle< OrderedHashSet > keys()
Definition keys.cc:125
V8_WARN_UNUSED_RESULT ExceptionStatus AddKey(Tagged< Object > key, AddKeyConversion convert=DO_NOT_CONVERT)
Definition keys.cc:129
DirectHandle< JSReceiver > receiver_
Definition keys.h:161
void set_try_prototype_info_cache(bool value)
Definition keys.h:146
KeyCollectionMode mode_
Definition keys.h:164
KeyCollectionMode mode()
Definition keys.h:89
Maybe< bool > CollectInterceptorKeys(DirectHandle< JSReceiver > receiver, DirectHandle< JSObject > object, IndexedOrNamed type)
Definition keys.cc:773
Handle< ObjectHashSet > shadowing_keys_
Definition keys.h:163
void set_receiver(DirectHandle< JSReceiver > object)
Definition keys.h:149
PropertyFilter filter_
Definition keys.h:165
KeyAccumulator & operator=(const KeyAccumulator &)=delete
void set_last_non_empty_prototype(DirectHandle< JSReceiver > object)
Definition keys.h:153
Maybe< bool > CollectOwnJSProxyKeys(DirectHandle< JSReceiver > receiver, DirectHandle< JSProxy > proxy)
Definition keys.cc:1220
void set_is_for_in(bool value)
Definition keys.h:142
static MaybeHandle< FixedArray > GetKeys(Isolate *isolate, DirectHandle< JSReceiver > object, KeyCollectionMode mode, PropertyFilter filter, GetKeysConversion keys_conversion=GetKeysConversion::kKeepNumbers, bool is_for_in=false, bool skip_indices=false)
Definition keys.cc:97
Maybe< bool > CollectOwnKeys(DirectHandle< JSReceiver > receiver, DirectHandle< JSObject > object)
Definition keys.cc:1138
Maybe< bool > CollectAccessCheckInterceptorKeys(DirectHandle< AccessCheckInfo > access_check_info, DirectHandle< JSReceiver > receiver, DirectHandle< JSObject > object)
Definition keys.cc:1113
void set_first_prototype_map(DirectHandle< Map > value)
Definition keys.h:143
PropertyFilter filter()
Definition keys.h:86
void set_skip_indices(bool value)
Definition keys.h:90
Maybe< bool > AddKeysFromJSProxy(DirectHandle< JSProxy > proxy, DirectHandle< FixedArray > keys)
Definition keys.cc:233
bool IsShadowed(DirectHandle< Object > key)
Definition keys.cc:303
Maybe< bool > CollectOwnElementIndices(DirectHandle< JSReceiver > receiver, DirectHandle< JSObject > object)
Definition keys.cc:788
static Handle< FixedArray > GetOwnEnumPropertyKeys(Isolate *isolate, DirectHandle< JSObject > object)
Definition keys.cc:1181
KeyAccumulator(Isolate *isolate, KeyCollectionMode mode, PropertyFilter filter)
Definition keys.h:52
DirectHandle< JSReceiver > last_non_empty_prototype_
Definition keys.h:162
V8_WARN_UNUSED_RESULT ExceptionStatus AddKeys(DirectHandle< FixedArray > array, AddKeyConversion convert)
Definition keys.cc:177
Handle< OrderedHashSet > keys_
Definition keys.h:159
DirectHandle< Map > first_prototype_map_
Definition keys.h:160
Maybe< bool > CollectInterceptorKeysInternal(DirectHandle< JSReceiver > receiver, DirectHandle< JSObject > object, DirectHandle< InterceptorInfo > interceptor, IndexedOrNamed type)
Definition keys.cc:736
TNode< Object > receiver
ZoneVector< RpoNumber > & result
KeyCollectionMode
Definition keys.h:28
GetKeysConversion
Definition keys.h:22
UnionOf< Undefined, FunctionTemplateInfo > UnionOf< Undefined, InterceptorInfo > UnionOf< Undefined, ObjectTemplateInfo > AccessCheckInfo
return value
Definition map-inl.h:893
AddKeyConversion
Definition keys.h:20
@ DO_NOT_CONVERT
Definition keys.h:20
@ CONVERT_TO_ARRAY_INDEX
Definition keys.h:20
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671