diff options
Diffstat (limited to 'deps/v8/src/objects/lookup.h')
-rw-r--r-- | deps/v8/src/objects/lookup.h | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/deps/v8/src/objects/lookup.h b/deps/v8/src/objects/lookup.h new file mode 100644 index 0000000000..820b8ef9b0 --- /dev/null +++ b/deps/v8/src/objects/lookup.h @@ -0,0 +1,281 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_LOOKUP_H_ +#define V8_OBJECTS_LOOKUP_H_ + +#include "src/common/globals.h" +#include "src/execution/isolate.h" +#include "src/heap/factory.h" +#include "src/objects/descriptor-array.h" +#include "src/objects/js-objects.h" +#include "src/objects/map.h" +#include "src/objects/objects.h" + +namespace v8 { +namespace internal { + +class V8_EXPORT_PRIVATE LookupIterator final { + public: + enum Configuration { + // Configuration bits. + kInterceptor = 1 << 0, + kPrototypeChain = 1 << 1, + + // Convenience combinations of bits. + OWN_SKIP_INTERCEPTOR = 0, + OWN = kInterceptor, + PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kPrototypeChain, + PROTOTYPE_CHAIN = kPrototypeChain | kInterceptor, + DEFAULT = PROTOTYPE_CHAIN + }; + + enum State { + ACCESS_CHECK, + INTEGER_INDEXED_EXOTIC, + INTERCEPTOR, + JSPROXY, + NOT_FOUND, + ACCESSOR, + DATA, + TRANSITION, + // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a + // PROPERTY lookup. + BEFORE_PROPERTY = INTERCEPTOR + }; + + inline LookupIterator(Isolate* isolate, Handle<Object> receiver, + Handle<Name> name, + Configuration configuration = DEFAULT); + + inline LookupIterator(Handle<Object> receiver, Handle<Name> name, + Handle<JSReceiver> holder, + Configuration configuration = DEFAULT); + + inline LookupIterator(Isolate* isolate, Handle<Object> receiver, + Handle<Name> name, Handle<JSReceiver> holder, + Configuration configuration = DEFAULT); + + inline LookupIterator(Isolate* isolate, Handle<Object> receiver, + uint32_t index, Configuration configuration = DEFAULT); + + LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index, + Handle<JSReceiver> holder, + Configuration configuration = DEFAULT) + : configuration_(configuration), + interceptor_state_(InterceptorState::kUninitialized), + property_details_(PropertyDetails::Empty()), + isolate_(isolate), + receiver_(receiver), + initial_holder_(holder), + index_(index), + number_(static_cast<uint32_t>(DescriptorArray::kNotFound)) { + // kMaxUInt32 isn't a valid index. + DCHECK_NE(kMaxUInt32, index_); + Start<true>(); + } + + static inline LookupIterator PropertyOrElement( + Isolate* isolate, Handle<Object> receiver, Handle<Name> name, + Configuration configuration = DEFAULT); + + static inline LookupIterator PropertyOrElement( + Isolate* isolate, Handle<Object> receiver, Handle<Name> name, + Handle<JSReceiver> holder, Configuration configuration = DEFAULT); + + static LookupIterator PropertyOrElement( + Isolate* isolate, Handle<Object> receiver, Handle<Object> key, + bool* success, Handle<JSReceiver> holder, + Configuration configuration = DEFAULT); + + static LookupIterator PropertyOrElement( + Isolate* isolate, Handle<Object> receiver, Handle<Object> key, + bool* success, Configuration configuration = DEFAULT); + + static LookupIterator ForTransitionHandler( + Isolate* isolate, Handle<Object> receiver, Handle<Name> name, + Handle<Object> value, MaybeHandle<Map> maybe_transition_map); + + void Restart() { + InterceptorState state = InterceptorState::kUninitialized; + IsElement() ? RestartInternal<true>(state) : RestartInternal<false>(state); + } + + Isolate* isolate() const { return isolate_; } + State state() const { return state_; } + + Handle<Name> name() const { + DCHECK(!IsElement()); + return name_; + } + inline Handle<Name> GetName(); + uint32_t index() const { return index_; } + + bool IsElement() const { return index_ != kMaxUInt32; } + + bool IsFound() const { return state_ != NOT_FOUND; } + void Next(); + void NotFound() { + has_property_ = false; + state_ = NOT_FOUND; + } + + Heap* heap() const { return isolate_->heap(); } + Factory* factory() const { return isolate_->factory(); } + Handle<Object> GetReceiver() const { return receiver_; } + + template <class T> + inline Handle<T> GetStoreTarget() const; + inline bool is_dictionary_holder() const; + inline Handle<Map> transition_map() const; + inline Handle<PropertyCell> transition_cell() const; + template <class T> + inline Handle<T> GetHolder() const; + + bool HolderIsReceiver() const; + bool HolderIsReceiverOrHiddenPrototype() const; + + bool check_prototype_chain() const { + return (configuration_ & kPrototypeChain) != 0; + } + + /* ACCESS_CHECK */ + bool HasAccess() const; + + /* PROPERTY */ + inline bool ExtendingNonExtensible(Handle<JSReceiver> receiver); + void PrepareForDataProperty(Handle<Object> value); + void PrepareTransitionToDataProperty(Handle<JSReceiver> receiver, + Handle<Object> value, + PropertyAttributes attributes, + StoreOrigin store_origin); + inline bool IsCacheableTransition(); + void ApplyTransitionToDataProperty(Handle<JSReceiver> receiver); + void ReconfigureDataProperty(Handle<Object> value, + PropertyAttributes attributes); + void Delete(); + void TransitionToAccessorProperty(Handle<Object> getter, + Handle<Object> setter, + PropertyAttributes attributes); + void TransitionToAccessorPair(Handle<Object> pair, + PropertyAttributes attributes); + PropertyDetails property_details() const { + DCHECK(has_property_); + return property_details_; + } + PropertyAttributes property_attributes() const { + return property_details().attributes(); + } + bool IsConfigurable() const { return property_details().IsConfigurable(); } + bool IsReadOnly() const { return property_details().IsReadOnly(); } + bool IsEnumerable() const { return property_details().IsEnumerable(); } + Representation representation() const { + return property_details().representation(); + } + PropertyLocation location() const { return property_details().location(); } + PropertyConstness constness() const { return property_details().constness(); } + Handle<Map> GetFieldOwnerMap() const; + FieldIndex GetFieldIndex() const; + Handle<FieldType> GetFieldType() const; + int GetFieldDescriptorIndex() const; + int GetAccessorIndex() const; + Handle<PropertyCell> GetPropertyCell() const; + Handle<Object> GetAccessors() const; + inline Handle<InterceptorInfo> GetInterceptor() const; + Handle<InterceptorInfo> GetInterceptorForFailedAccessCheck() const; + Handle<Object> GetDataValue() const; + void WriteDataValue(Handle<Object> value, bool initializing_store); + inline void UpdateProtector(); + + // Lookup a 'cached' private property for an accessor. + // If not found returns false and leaves the LookupIterator unmodified. + bool TryLookupCachedProperty(); + bool LookupCachedProperty(); + + private: + // For |ForTransitionHandler|. + LookupIterator(Isolate* isolate, Handle<Object> receiver, Handle<Name> name, + Handle<Map> transition_map, PropertyDetails details, + bool has_property); + + void InternalUpdateProtector(); + + enum class InterceptorState { + kUninitialized, + kSkipNonMasking, + kProcessNonMasking + }; + + Handle<Map> GetReceiverMap() const; + + V8_WARN_UNUSED_RESULT inline JSReceiver NextHolder(Map map); + + template <bool is_element> + V8_EXPORT_PRIVATE void Start(); + template <bool is_element> + void NextInternal(Map map, JSReceiver holder); + template <bool is_element> + inline State LookupInHolder(Map map, JSReceiver holder) { + return map.IsSpecialReceiverMap() + ? LookupInSpecialHolder<is_element>(map, holder) + : LookupInRegularHolder<is_element>(map, holder); + } + template <bool is_element> + State LookupInRegularHolder(Map map, JSReceiver holder); + template <bool is_element> + State LookupInSpecialHolder(Map map, JSReceiver holder); + template <bool is_element> + void RestartLookupForNonMaskingInterceptors() { + RestartInternal<is_element>(InterceptorState::kProcessNonMasking); + } + template <bool is_element> + void RestartInternal(InterceptorState interceptor_state); + Handle<Object> FetchValue() const; + bool IsConstFieldValueEqualTo(Object value) const; + template <bool is_element> + void ReloadPropertyInformation(); + + template <bool is_element> + bool SkipInterceptor(JSObject holder); + template <bool is_element> + static inline InterceptorInfo GetInterceptor(JSObject holder); + + bool check_interceptor() const { + return (configuration_ & kInterceptor) != 0; + } + inline int descriptor_number() const; + inline int dictionary_entry() const; + + static inline Configuration ComputeConfiguration(Configuration configuration, + Handle<Name> name); + + static Handle<JSReceiver> GetRootForNonJSReceiver( + Isolate* isolate, Handle<Object> receiver, uint32_t index = kMaxUInt32); + static inline Handle<JSReceiver> GetRoot(Isolate* isolate, + Handle<Object> receiver, + uint32_t index = kMaxUInt32); + + State NotFound(JSReceiver const holder) const; + + // If configuration_ becomes mutable, update + // HolderIsReceiverOrHiddenPrototype. + const Configuration configuration_; + State state_; + bool has_property_; + InterceptorState interceptor_state_; + PropertyDetails property_details_; + Isolate* const isolate_; + Handle<Name> name_; + Handle<Object> transition_; + const Handle<Object> receiver_; + Handle<JSReceiver> holder_; + const Handle<JSReceiver> initial_holder_; + const uint32_t index_; + uint32_t number_; +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_OBJECTS_LOOKUP_H_ |