1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_LOOKUP_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_LOOKUP_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/factory.h"
9c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/globals.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/objects.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE LookupIterator final BASE_EMBEDDED {
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Configuration {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Configuration bits.
20bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    kInterceptor = 1 << 0,
21bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    kPrototypeChain = 1 << 1,
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Convience combinations of bits.
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OWN_SKIP_INTERCEPTOR = 0,
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OWN = kInterceptor,
26bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kPrototypeChain,
27bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PROTOTYPE_CHAIN = kPrototypeChain | kInterceptor,
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DEFAULT = PROTOTYPE_CHAIN
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum State {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ACCESS_CHECK,
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    INTEGER_INDEXED_EXOTIC,
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    INTERCEPTOR,
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JSPROXY,
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NOT_FOUND,
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ACCESSOR,
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DATA,
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TRANSITION,
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // PROPERTY lookup.
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BEFORE_PROPERTY = INTERCEPTOR
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LookupIterator(Handle<Object> receiver, Handle<Name> name,
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 Configuration configuration = DEFAULT)
47f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : LookupIterator(name->GetIsolate(), receiver, name, configuration) {}
48f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  LookupIterator(Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
50f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                 Configuration configuration = DEFAULT)
51f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : LookupIterator(isolate, receiver, name, GetRoot(isolate, receiver),
52f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       configuration) {}
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LookupIterator(Handle<Object> receiver, Handle<Name> name,
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 Handle<JSReceiver> holder,
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 Configuration configuration = DEFAULT)
57f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : LookupIterator(name->GetIsolate(), receiver, name, holder,
58f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       configuration) {}
59f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
60f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  LookupIterator(Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
61f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                 Handle<JSReceiver> holder,
62f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                 Configuration configuration = DEFAULT)
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : configuration_(ComputeConfiguration(configuration, name)),
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        interceptor_state_(InterceptorState::kUninitialized),
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        property_details_(PropertyDetails::Empty()),
66f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        isolate_(isolate),
67109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        name_(isolate_->factory()->InternalizeName(name)),
683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        receiver_(receiver),
693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        initial_holder_(holder),
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // kMaxUInt32 isn't a valid index.
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        index_(kMaxUInt32),
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        number_(DescriptorArray::kNotFound) {
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t index;  // Assert that the name is not an array index.
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!name->AsArrayIndex(&index));
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // DEBUG
773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Start<false>();
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index,
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 Configuration configuration = DEFAULT)
82f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : LookupIterator(isolate, receiver, index,
83f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       GetRoot(isolate, receiver, index), configuration) {}
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index,
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 Handle<JSReceiver> holder,
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 Configuration configuration = DEFAULT)
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : configuration_(configuration),
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        interceptor_state_(InterceptorState::kUninitialized),
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        property_details_(PropertyDetails::Empty()),
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_(isolate),
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        receiver_(receiver),
933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        initial_holder_(holder),
943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        index_(index),
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        number_(DescriptorArray::kNotFound) {
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // kMaxUInt32 isn't a valid index.
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NE(kMaxUInt32, index_);
983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Start<true>();
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static LookupIterator PropertyOrElement(
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Configuration configuration = DEFAULT) {
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t index;
105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (name->AsArrayIndex(&index)) {
106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      LookupIterator it =
107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          LookupIterator(isolate, receiver, index, configuration);
108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      it.name_ = name;
109109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return it;
110109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
111109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return LookupIterator(receiver, name, configuration);
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static LookupIterator PropertyOrElement(
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<JSReceiver> holder, Configuration configuration = DEFAULT) {
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t index;
118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (name->AsArrayIndex(&index)) {
119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      LookupIterator it =
120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          LookupIterator(isolate, receiver, index, holder, configuration);
121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      it.name_ = name;
122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return it;
123109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return LookupIterator(receiver, name, holder, configuration);
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static LookupIterator PropertyOrElement(
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Handle<Object> receiver, Handle<Object> key,
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool* success, Configuration configuration = DEFAULT);
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void Restart() {
1323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    InterceptorState state = InterceptorState::kUninitialized;
1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    IsElement() ? RestartInternal<true>(state) : RestartInternal<false>(state);
1343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return isolate_; }
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  State state() const { return state_; }
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Name> name() const {
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!IsElement());
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return name_;
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Name> GetName() {
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (name_.is_null()) {
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(IsElement());
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      name_ = factory()->Uint32ToString(index_);
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return name_;
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t index() const { return index_; }
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsElement() const { return index_ != kMaxUInt32; }
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsFound() const { return state_ != NOT_FOUND; }
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Next();
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void NotFound() {
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_property_ = false;
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    state_ = NOT_FOUND;
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap* heap() const { return isolate_->heap(); }
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Factory* factory() const { return isolate_->factory(); }
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> GetReceiver() const { return receiver_; }
1643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Handle<JSObject> GetStoreTarget() const {
16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK(receiver_->IsJSObject());
1673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (receiver_->IsJSGlobalProxy()) {
1683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Map* map = JSGlobalProxy::cast(*receiver_)->map();
1693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (map->has_hidden_prototype()) {
1703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return handle(JSGlobalObject::cast(map->prototype()), isolate_);
1713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
1723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
1733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return Handle<JSObject>::cast(receiver_);
1743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool is_dictionary_holder() const { return !holder_->HasFastProperties(); }
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Map> transition_map() const {
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(TRANSITION, state_);
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Handle<Map>::cast(transition_);
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<PropertyCell> transition_cell() const {
182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_EQ(TRANSITION, state_);
183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return Handle<PropertyCell>::cast(transition_);
184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class T>
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<T> GetHolder() const {
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsFound());
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<T>::cast(holder_);
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HolderIsReceiverOrHiddenPrototype() const;
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool check_prototype_chain() const {
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (configuration_ & kPrototypeChain) != 0;
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  /* ACCESS_CHECK */
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasAccess() const;
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  /* PROPERTY */
201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool ExtendingNonExtensible(Handle<JSObject> receiver) {
202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(receiver.is_identical_to(GetStoreTarget()));
203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return !receiver->map()->is_extensible() &&
204109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           (IsElement() || !name_->IsPrivate());
205109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PrepareForDataProperty(Handle<Object> value);
207109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void PrepareTransitionToDataProperty(Handle<JSObject> receiver,
208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                       Handle<Object> value,
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       PropertyAttributes attributes,
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       Object::StoreFromKeyed store_mode);
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsCacheableTransition() {
212109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK_EQ(TRANSITION, state_);
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return transition_->IsPropertyCell() ||
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           (!transition_map()->is_dictionary_map() &&
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            transition_map()->GetBackPointer()->IsMap());
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void ApplyTransitionToDataProperty(Handle<JSObject> receiver);
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ReconfigureDataProperty(Handle<Object> value,
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               PropertyAttributes attributes);
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Delete();
221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void TransitionToAccessorProperty(Handle<Object> getter,
222bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                    Handle<Object> setter,
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    PropertyAttributes attributes);
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void TransitionToAccessorPair(Handle<Object> pair,
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                PropertyAttributes attributes);
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PropertyDetails property_details() const {
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(has_property_);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return property_details_;
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PropertyAttributes property_attributes() const {
231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return property_details().attributes();
232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConfigurable() const { return property_details().IsConfigurable(); }
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsReadOnly() const { return property_details().IsReadOnly(); }
235109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool IsEnumerable() const { return property_details().IsEnumerable(); }
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation representation() const {
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return property_details().representation();
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  PropertyLocation location() const { return property_details().location(); }
24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  PropertyConstness constness() const { return property_details().constness(); }
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<Map> GetFieldOwnerMap() const;
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FieldIndex GetFieldIndex() const;
243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Handle<FieldType> GetFieldType() const;
244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int GetFieldDescriptorIndex() const;
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int GetAccessorIndex() const;
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int GetConstantIndex() const;
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<PropertyCell> GetPropertyCell() const;
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> GetAccessors() const;
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline Handle<InterceptorInfo> GetInterceptor() const {
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(INTERCEPTOR, state_);
2513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    InterceptorInfo* result =
2523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        IsElement() ? GetInterceptor<true>(JSObject::cast(*holder_))
2533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                    : GetInterceptor<false>(JSObject::cast(*holder_));
2543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return handle(result, isolate_);
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
25613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<InterceptorInfo> GetInterceptorForFailedAccessCheck() const;
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> GetDataValue() const;
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void WriteDataValue(Handle<Object> value, bool initializing_store);
2593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  inline void UpdateProtector() {
260bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (IsElement()) return;
261bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (*name_ == heap()->is_concat_spreadable_symbol() ||
26213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        *name_ == heap()->constructor_string() ||
26313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        *name_ == heap()->species_symbol() ||
264c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        *name_ == heap()->has_instance_symbol() ||
265c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        *name_ == heap()->iterator_symbol()) {
2663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      InternalUpdateProtector();
2673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
2683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
270c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Lookup a 'cached' private property for an accessor.
271c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // If not found returns false and leaves the LookupIterator unmodified.
272c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool TryLookupCachedProperty();
273c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool LookupCachedProperty();
274c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void InternalUpdateProtector();
2773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum class InterceptorState {
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kUninitialized,
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kSkipNonMasking,
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kProcessNonMasking
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Map> GetReceiverMap() const;
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map);
2873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8_EXPORT_PRIVATE void Start();
2903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
2913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void NextInternal(Map* map, JSReceiver* holder);
2923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
2933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  inline State LookupInHolder(Map* map, JSReceiver* holder) {
29462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return map->IsSpecialReceiverMap()
2953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch               ? LookupInSpecialHolder<is_element>(map, holder)
2963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch               : LookupInRegularHolder<is_element>(map, holder);
2973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
2983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
2993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  State LookupInRegularHolder(Map* map, JSReceiver* holder);
3003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
3013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  State LookupInSpecialHolder(Map* map, JSReceiver* holder);
3023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RestartLookupForNonMaskingInterceptors() {
3043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    RestartInternal<is_element>(InterceptorState::kProcessNonMasking);
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RestartInternal(InterceptorState interceptor_state);
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> FetchValue() const;
30962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsConstFieldValueEqualTo(Object* value) const;
3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ReloadPropertyInformation();
3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
3143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool SkipInterceptor(JSObject* holder);
3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  template <bool is_element>
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline InterceptorInfo* GetInterceptor(JSObject* holder) const {
3173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return is_element ? holder->GetIndexedInterceptor()
3183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      : holder->GetNamedInterceptor();
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool check_interceptor() const {
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (configuration_ & kInterceptor) != 0;
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int descriptor_number() const {
325109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!IsElement());
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(has_property_);
327109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(holder_->HasFastProperties());
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return number_;
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int dictionary_entry() const {
331109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!IsElement());
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(has_property_);
333109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!holder_->HasFastProperties());
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return number_;
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Configuration ComputeConfiguration(
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Configuration configuration, Handle<Name> name) {
339bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return name->IsPrivate() ? OWN_SKIP_INTERCEPTOR : configuration;
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static Handle<JSReceiver> GetRootForNonJSReceiver(
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Handle<Object> receiver, uint32_t index = kMaxUInt32);
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline static Handle<JSReceiver> GetRoot(Isolate* isolate,
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           Handle<Object> receiver,
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           uint32_t index = kMaxUInt32) {
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return GetRootForNonJSReceiver(isolate, receiver, index);
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  State NotFound(JSReceiver* const holder) const;
352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If configuration_ becomes mutable, update
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // HolderIsReceiverOrHiddenPrototype.
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Configuration configuration_;
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  State state_;
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_property_;
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InterceptorState interceptor_state_;
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PropertyDetails property_details_;
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* const isolate_;
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Name> name_;
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> transition_;
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Handle<Object> receiver_;
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSReceiver> holder_;
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Handle<JSReceiver> initial_holder_;
3663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const uint32_t index_;
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t number_;
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_LOOKUP_H_
375