• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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_LOOKUP_H_
6 #define V8_LOOKUP_H_
7 
8 #include "src/factory.h"
9 #include "src/isolate.h"
10 #include "src/objects.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 class LookupIterator V8_FINAL BASE_EMBEDDED {
16  public:
17   enum Configuration {
18     CHECK_OWN_REAL     = 0,
19     CHECK_HIDDEN       = 1 << 0,
20     CHECK_DERIVED      = 1 << 1,
21     CHECK_INTERCEPTOR  = 1 << 2,
22     CHECK_ACCESS_CHECK = 1 << 3,
23     CHECK_ALL          = CHECK_HIDDEN | CHECK_DERIVED |
24                          CHECK_INTERCEPTOR | CHECK_ACCESS_CHECK,
25     SKIP_INTERCEPTOR   = CHECK_ALL ^ CHECK_INTERCEPTOR,
26     CHECK_OWN          = CHECK_ALL ^ CHECK_DERIVED
27   };
28 
29   enum State {
30     NOT_FOUND,
31     PROPERTY,
32     INTERCEPTOR,
33     ACCESS_CHECK,
34     JSPROXY
35   };
36 
37   enum PropertyKind {
38     DATA,
39     ACCESSOR
40   };
41 
42   enum PropertyEncoding {
43     DICTIONARY,
44     DESCRIPTOR
45   };
46 
47   LookupIterator(Handle<Object> receiver,
48                  Handle<Name> name,
49                  Configuration configuration = CHECK_ALL)
configuration_(configuration)50       : configuration_(configuration),
51         state_(NOT_FOUND),
52         property_kind_(DATA),
53         property_encoding_(DESCRIPTOR),
54         property_details_(NONE, NONEXISTENT, Representation::None()),
55         isolate_(name->GetIsolate()),
56         name_(name),
57         maybe_receiver_(receiver),
58         number_(DescriptorArray::kNotFound) {
59     Handle<JSReceiver> root = GetRoot();
60     holder_map_ = handle(root->map());
61     maybe_holder_ = root;
62     Next();
63   }
64 
65   LookupIterator(Handle<Object> receiver,
66                  Handle<Name> name,
67                  Handle<JSReceiver> holder,
68                  Configuration configuration = CHECK_ALL)
configuration_(configuration)69       : configuration_(configuration),
70         state_(NOT_FOUND),
71         property_kind_(DATA),
72         property_encoding_(DESCRIPTOR),
73         property_details_(NONE, NONEXISTENT, Representation::None()),
74         isolate_(name->GetIsolate()),
75         name_(name),
76         holder_map_(holder->map()),
77         maybe_receiver_(receiver),
78         maybe_holder_(holder),
79         number_(DescriptorArray::kNotFound) {
80     Next();
81   }
82 
isolate()83   Isolate* isolate() const { return isolate_; }
state()84   State state() const { return state_; }
name()85   Handle<Name> name() const { return name_; }
86 
IsFound()87   bool IsFound() const { return state_ != NOT_FOUND; }
88   void Next();
89 
heap()90   Heap* heap() const { return isolate_->heap(); }
factory()91   Factory* factory() const { return isolate_->factory(); }
GetReceiver()92   Handle<Object> GetReceiver() const {
93     return Handle<Object>::cast(maybe_receiver_.ToHandleChecked());
94   }
GetHolder()95   Handle<JSObject> GetHolder() const {
96     ASSERT(IsFound() && state_ != JSPROXY);
97     return Handle<JSObject>::cast(maybe_holder_.ToHandleChecked());
98   }
99   Handle<JSReceiver> GetRoot() const;
100 
101   /* Dynamically reduce the trapped types. */
skip_interceptor()102   void skip_interceptor() {
103     configuration_ = static_cast<Configuration>(
104         configuration_ & ~CHECK_INTERCEPTOR);
105   }
skip_access_check()106   void skip_access_check() {
107     configuration_ = static_cast<Configuration>(
108         configuration_ & ~CHECK_ACCESS_CHECK);
109   }
110 
111   /* ACCESS_CHECK */
112   bool HasAccess(v8::AccessType access_type) const;
113 
114   /* PROPERTY */
115   // HasProperty needs to be called before any of the other PROPERTY methods
116   // below can be used. It ensures that we are able to provide a definite
117   // answer, and loads extra information about the property.
118   bool HasProperty();
property_kind()119   PropertyKind property_kind() const {
120     ASSERT(has_property_);
121     return property_kind_;
122   }
property_details()123   PropertyDetails property_details() const {
124     ASSERT(has_property_);
125     return property_details_;
126   }
127   Handle<Object> GetAccessors() const;
128   Handle<Object> GetDataValue() const;
129 
130   /* JSPROXY */
131 
GetJSProxy()132   Handle<JSProxy> GetJSProxy() const {
133     return Handle<JSProxy>::cast(maybe_holder_.ToHandleChecked());
134   }
135 
136  private:
137   Handle<Map> GetReceiverMap() const;
138 
139   MUST_USE_RESULT bool NextHolder();
140   State LookupInHolder();
141   Handle<Object> FetchValue() const;
142 
143   bool IsBootstrapping() const;
144 
145   // Methods that fetch data from the holder ensure they always have a holder.
146   // This means the receiver needs to be present as opposed to just the receiver
147   // map. Other objects in the prototype chain are transitively guaranteed to be
148   // present via the receiver map.
is_guaranteed_to_have_holder()149   bool is_guaranteed_to_have_holder() const {
150     return !maybe_receiver_.is_null();
151   }
check_interceptor()152   bool check_interceptor() const {
153     return !IsBootstrapping() && (configuration_ & CHECK_INTERCEPTOR) != 0;
154   }
check_derived()155   bool check_derived() const {
156     return (configuration_ & CHECK_DERIVED) != 0;
157   }
check_hidden()158   bool check_hidden() const {
159     return (configuration_ & CHECK_HIDDEN) != 0;
160   }
check_access_check()161   bool check_access_check() const {
162     return (configuration_ & CHECK_ACCESS_CHECK) != 0;
163   }
164 
165   Configuration configuration_;
166   State state_;
167   bool has_property_;
168   PropertyKind property_kind_;
169   PropertyEncoding property_encoding_;
170   PropertyDetails property_details_;
171   Isolate* isolate_;
172   Handle<Name> name_;
173   Handle<Map> holder_map_;
174   MaybeHandle<Object> maybe_receiver_;
175   MaybeHandle<JSReceiver> maybe_holder_;
176 
177   int number_;
178 };
179 
180 
181 } }  // namespace v8::internal
182 
183 #endif  // V8_LOOKUP_H_
184