blob: 0f78ba478ec8512e8d94fd57a502a42a470c582a [file] [log] [blame]
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_PROPERTY_H_
29#define V8_PROPERTY_H_
30
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000032#include "transitions.h"
lrn@chromium.org1c092762011-05-09 09:42:16 +000033
kasperl@chromium.org71affb52009-05-26 05:44:31 +000034namespace v8 {
35namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036
37
38// Abstraction for elements in instance-descriptor arrays.
39//
40// Each descriptor has a key, property attributes, property type,
41// property index (in the actual instance-descriptor array) and
42// optionally a piece of data.
43//
44
45class Descriptor BASE_EMBEDDED {
46 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +000047 MUST_USE_RESULT MaybeObject* KeyToUniqueName() {
48 if (!key_->IsUniqueName()) {
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +000049 MaybeObject* maybe_result =
50 key_->GetIsolate()->heap()->InternalizeString(String::cast(key_));
erik.corry@gmail.combbceb572012-03-09 10:52:05 +000051 if (!maybe_result->To(&key_)) return maybe_result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000052 }
53 return key_;
54 }
55
ulan@chromium.org750145a2013-03-07 15:14:13 +000056 Name* GetKey() { return key_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000057 Object* GetValue() { return value_; }
58 PropertyDetails GetDetails() { return details_; }
59
whesse@chromium.org023421e2010-12-21 12:19:12 +000060#ifdef OBJECT_PRINT
61 void Print(FILE* out);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000062#endif
63
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +000064 void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +000065
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066 private:
ulan@chromium.org750145a2013-03-07 15:14:13 +000067 Name* key_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000068 Object* value_;
69 PropertyDetails details_;
70
71 protected:
72 Descriptor() : details_(Smi::FromInt(0)) {}
73
ulan@chromium.org750145a2013-03-07 15:14:13 +000074 void Init(Name* key, Object* value, PropertyDetails details) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000075 key_ = key;
76 value_ = value;
77 details_ = details;
78 }
79
ulan@chromium.org750145a2013-03-07 15:14:13 +000080 Descriptor(Name* key, Object* value, PropertyDetails details)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 : key_(key),
82 value_(value),
83 details_(details) { }
84
ulan@chromium.org750145a2013-03-07 15:14:13 +000085 Descriptor(Name* key,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000086 Object* value,
87 PropertyAttributes attributes,
88 PropertyType type,
rossberg@chromium.org79e79022013-06-03 15:43:46 +000089 Representation representation,
90 int field_index = 0)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000091 : key_(key),
92 value_(value),
rossberg@chromium.org79e79022013-06-03 15:43:46 +000093 details_(attributes, type, representation, field_index) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095 friend class DescriptorArray;
96};
97
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000098
99class FieldDescriptor: public Descriptor {
100 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +0000101 FieldDescriptor(Name* key,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000102 int field_index,
103 PropertyAttributes attributes,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000104 Representation representation)
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000105 : Descriptor(key, Smi::FromInt(0), attributes,
106 FIELD, representation, field_index) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000107};
108
109
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000110class ConstantDescriptor: public Descriptor {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000111 public:
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000112 ConstantDescriptor(Name* key,
113 Object* value,
114 PropertyAttributes attributes)
115 : Descriptor(key, value, attributes, CONSTANT,
116 value->OptimalRepresentation()) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000117};
118
119
120class CallbacksDescriptor: public Descriptor {
121 public:
ulan@chromium.org750145a2013-03-07 15:14:13 +0000122 CallbacksDescriptor(Name* key,
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000123 Object* foreign,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000124 PropertyAttributes attributes)
danno@chromium.orgf005df62013-04-30 16:36:45 +0000125 : Descriptor(key, foreign, attributes, CALLBACKS,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000126 Representation::Tagged()) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000127};
128
129
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000130// Holds a property index value distinguishing if it is a field index or an
131// index inside the object header.
132class PropertyIndex {
133 public:
134 static PropertyIndex NewFieldIndex(int index) {
135 return PropertyIndex(index, false);
136 }
137 static PropertyIndex NewHeaderIndex(int index) {
138 return PropertyIndex(index, true);
139 }
140
141 bool is_field_index() { return (index_ & kHeaderIndexBit) == 0; }
142 bool is_header_index() { return (index_ & kHeaderIndexBit) != 0; }
143
144 int field_index() {
145 ASSERT(is_field_index());
146 return value();
147 }
148 int header_index() {
149 ASSERT(is_header_index());
150 return value();
151 }
152
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000153 bool is_inobject(Handle<JSObject> holder) {
154 if (is_header_index()) return true;
155 return field_index() < holder->map()->inobject_properties();
156 }
157
158 int translate(Handle<JSObject> holder) {
159 if (is_header_index()) return header_index();
160 int index = field_index() - holder->map()->inobject_properties();
161 if (index >= 0) return index;
162 return index + holder->map()->instance_size() / kPointerSize;
163 }
164
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000165 private:
166 static const int kHeaderIndexBit = 1 << 31;
167 static const int kIndexMask = ~kHeaderIndexBit;
168
169 int value() { return index_ & kIndexMask; }
170
171 PropertyIndex(int index, bool is_header_based)
172 : index_(index | (is_header_based ? kHeaderIndexBit : 0)) {
173 ASSERT(index <= kIndexMask);
174 }
175
176 int index_;
177};
178
179
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000180class LookupResult BASE_EMBEDDED {
181 public:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000182 explicit LookupResult(Isolate* isolate)
183 : isolate_(isolate),
184 next_(isolate->top_lookup_result()),
185 lookup_type_(NOT_FOUND),
186 holder_(NULL),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000187 cacheable_(true),
danno@chromium.orgf005df62013-04-30 16:36:45 +0000188 details_(NONE, NONEXISTENT, Representation::None()) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000189 isolate->SetTopLookupResult(this);
190 }
191
192 ~LookupResult() {
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000193 ASSERT(isolate()->top_lookup_result() == this);
194 isolate()->SetTopLookupResult(next_);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000195 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000197 Isolate* isolate() const { return isolate_; }
198
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000199 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
200 lookup_type_ = DESCRIPTOR_TYPE;
201 holder_ = holder;
202 details_ = details;
203 number_ = number;
204 }
205
danno@chromium.orgf005df62013-04-30 16:36:45 +0000206 bool CanHoldValue(Handle<Object> value) {
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000207 if (IsNormal()) return true;
208 ASSERT(!IsTransition());
danno@chromium.orgf005df62013-04-30 16:36:45 +0000209 return value->FitsRepresentation(details_.representation());
210 }
211
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000212 void TransitionResult(JSObject* holder, int number) {
213 lookup_type_ = TRANSITION_TYPE;
danno@chromium.orgf005df62013-04-30 16:36:45 +0000214 details_ = PropertyDetails(NONE, TRANSITION, Representation::None());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000215 holder_ = holder;
216 number_ = number;
217 }
218
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000219 void DictionaryResult(JSObject* holder, int entry) {
220 lookup_type_ = DICTIONARY_TYPE;
221 holder_ = holder;
222 details_ = holder->property_dictionary()->DetailsAt(entry);
223 number_ = entry;
224 }
225
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000226 void HandlerResult(JSProxy* proxy) {
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000227 lookup_type_ = HANDLER_TYPE;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000228 holder_ = proxy;
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000229 details_ = PropertyDetails(NONE, HANDLER, Representation::Tagged());
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000230 cacheable_ = false;
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000231 }
232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000233 void InterceptorResult(JSObject* holder) {
234 lookup_type_ = INTERCEPTOR_TYPE;
235 holder_ = holder;
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000236 details_ = PropertyDetails(NONE, INTERCEPTOR, Representation::Tagged());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237 }
238
239 void NotFound() {
240 lookup_type_ = NOT_FOUND;
danno@chromium.orgf005df62013-04-30 16:36:45 +0000241 details_ = PropertyDetails(NONE, NONEXISTENT, Representation::None());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000242 holder_ = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243 }
244
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000245 JSObject* holder() {
ager@chromium.org5c838252010-02-19 08:53:10 +0000246 ASSERT(IsFound());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000247 return JSObject::cast(holder_);
248 }
249
250 JSProxy* proxy() {
251 ASSERT(IsFound());
252 return JSProxy::cast(holder_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000253 }
254
255 PropertyType type() {
ager@chromium.org5c838252010-02-19 08:53:10 +0000256 ASSERT(IsFound());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257 return details_.type();
258 }
259
danno@chromium.orgf005df62013-04-30 16:36:45 +0000260 Representation representation() {
261 ASSERT(IsFound());
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000262 ASSERT(!IsTransition());
263 ASSERT(details_.type() != NONEXISTENT);
danno@chromium.orgf005df62013-04-30 16:36:45 +0000264 return details_.representation();
265 }
266
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000267 PropertyAttributes GetAttributes() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000268 ASSERT(!IsTransition());
ager@chromium.org5c838252010-02-19 08:53:10 +0000269 ASSERT(IsFound());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000270 ASSERT(details_.type() != NONEXISTENT);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000271 return details_.attributes();
272 }
273
274 PropertyDetails GetPropertyDetails() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000275 ASSERT(!IsTransition());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000276 return details_;
277 }
278
yangguo@chromium.orgde0db002012-06-22 13:44:28 +0000279 bool IsFastPropertyType() {
280 ASSERT(IsFound());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000281 return IsTransition() || type() != NORMAL;
282 }
283
284 // Property callbacks does not include transitions to callbacks.
285 bool IsPropertyCallbacks() {
286 ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
287 return details_.type() == CALLBACKS;
288 }
289
yangguo@chromium.orgde0db002012-06-22 13:44:28 +0000290 bool IsReadOnly() {
291 ASSERT(IsFound());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000292 ASSERT(!IsTransition());
293 ASSERT(details_.type() != NONEXISTENT);
yangguo@chromium.orgde0db002012-06-22 13:44:28 +0000294 return details_.IsReadOnly();
295 }
296
yangguo@chromium.orgde0db002012-06-22 13:44:28 +0000297 bool IsField() {
298 ASSERT(!(details_.type() == FIELD && !IsFound()));
299 return details_.type() == FIELD;
300 }
301
302 bool IsNormal() {
303 ASSERT(!(details_.type() == NORMAL && !IsFound()));
304 return details_.type() == NORMAL;
305 }
306
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000307 bool IsConstant() {
308 ASSERT(!(details_.type() == CONSTANT && !IsFound()));
309 return details_.type() == CONSTANT;
310 }
311
yangguo@chromium.orgde0db002012-06-22 13:44:28 +0000312 bool IsConstantFunction() {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000313 return IsConstant() && GetValue()->IsJSFunction();
yangguo@chromium.orgde0db002012-06-22 13:44:28 +0000314 }
315
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000316 bool IsDontDelete() { return details_.IsDontDelete(); }
317 bool IsDontEnum() { return details_.IsDontEnum(); }
ager@chromium.org5c838252010-02-19 08:53:10 +0000318 bool IsFound() { return lookup_type_ != NOT_FOUND; }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000319 bool IsTransition() { return lookup_type_ == TRANSITION_TYPE; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000320 bool IsHandler() { return lookup_type_ == HANDLER_TYPE; }
yangguo@chromium.orgde0db002012-06-22 13:44:28 +0000321 bool IsInterceptor() { return lookup_type_ == INTERCEPTOR_TYPE; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000322
ulan@chromium.org9a21ec42012-03-06 08:42:24 +0000323 // Is the result is a property excluding transitions and the null descriptor?
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000324 bool IsProperty() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000325 return IsFound() && !IsTransition();
ager@chromium.org5c838252010-02-19 08:53:10 +0000326 }
327
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000328 bool IsDataProperty() {
329 switch (type()) {
330 case FIELD:
331 case NORMAL:
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000332 case CONSTANT:
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000333 return true;
334 case CALLBACKS: {
335 Object* callback = GetCallbackObject();
336 return callback->IsAccessorInfo() || callback->IsForeign();
337 }
338 case HANDLER:
339 case INTERCEPTOR:
340 case TRANSITION:
341 case NONEXISTENT:
342 return false;
343 }
344 UNREACHABLE();
345 return false;
346 }
347
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000348 bool IsCacheable() { return cacheable_; }
349 void DisallowCaching() { cacheable_ = false; }
350
ager@chromium.org3a37e9b2009-04-27 09:26:21 +0000351 Object* GetLazyValue() {
352 switch (type()) {
353 case FIELD:
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000354 return holder()->RawFastPropertyAt(GetFieldIndex().field_index());
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000355 case NORMAL: {
356 Object* value;
357 value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry());
358 if (holder()->IsGlobalObject()) {
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000359 value = PropertyCell::cast(value)->value();
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000360 }
361 return value;
362 }
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000363 case CONSTANT:
364 return GetConstant();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000365 case CALLBACKS:
366 case HANDLER:
367 case INTERCEPTOR:
368 case TRANSITION:
369 case NONEXISTENT:
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000370 return isolate()->heap()->the_hole_value();
ager@chromium.org3a37e9b2009-04-27 09:26:21 +0000371 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000372 UNREACHABLE();
373 return NULL;
ager@chromium.org3a37e9b2009-04-27 09:26:21 +0000374 }
375
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000376 Map* GetTransitionTarget(Map* map) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000377 ASSERT(IsTransition());
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000378 TransitionArray* transitions = map->transitions();
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000379 return transitions->GetTarget(number_);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000380 }
381
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000382 Map* GetTransitionTarget() {
383 return GetTransitionTarget(holder()->map());
384 }
385
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000386 PropertyDetails GetTransitionDetails(Map* map) {
387 ASSERT(IsTransition());
388 TransitionArray* transitions = map->transitions();
389 return transitions->GetTargetDetails(number_);
390 }
391
392 PropertyDetails GetTransitionDetails() {
393 return GetTransitionDetails(holder()->map());
394 }
395
396 bool IsTransitionToField(Map* map) {
397 return IsTransition() && GetTransitionDetails(map).type() == FIELD;
398 }
399
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000400 bool IsTransitionToConstant(Map* map) {
401 return IsTransition() && GetTransitionDetails(map).type() == CONSTANT;
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000402 }
403
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000404 Map* GetTransitionMap() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000405 ASSERT(IsTransition());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000406 return Map::cast(GetValue());
407 }
408
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000409 Map* GetTransitionMapFromMap(Map* map) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000410 ASSERT(IsTransition());
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000411 return map->transitions()->GetTarget(number_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000412 }
413
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000414 int GetTransitionIndex() {
415 ASSERT(IsTransition());
416 return number_;
417 }
418
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000419 int GetDescriptorIndex() {
420 ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
421 return number_;
422 }
423
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000424 PropertyIndex GetFieldIndex() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000425 ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000426 return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000427 }
428
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000429 int GetLocalFieldIndexFromMap(Map* map) {
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000430 return GetFieldIndexFromMap(map) - map->inobject_properties();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000431 }
432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433 int GetDictionaryEntry() {
434 ASSERT(lookup_type_ == DICTIONARY_TYPE);
435 return number_;
436 }
437
438 JSFunction* GetConstantFunction() {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000439 ASSERT(type() == CONSTANT);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000440 return JSFunction::cast(GetValue());
441 }
442
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000443 Object* GetConstantFromMap(Map* map) {
444 ASSERT(type() == CONSTANT);
445 return GetValueFromMap(map);
446 }
447
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000448 JSFunction* GetConstantFunctionFromMap(Map* map) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000449 return JSFunction::cast(GetConstantFromMap(map));
450 }
451
452 Object* GetConstant() {
453 ASSERT(type() == CONSTANT);
454 return GetValue();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000455 }
456
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000457 Object* GetCallbackObject() {
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +0000458 ASSERT(type() == CALLBACKS && !IsTransition());
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000459 return GetValue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000460 }
461
whesse@chromium.org023421e2010-12-21 12:19:12 +0000462#ifdef OBJECT_PRINT
463 void Print(FILE* out);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464#endif
465
466 Object* GetValue() {
467 if (lookup_type_ == DESCRIPTOR_TYPE) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000468 return GetValueFromMap(holder()->map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000469 }
470 // In the dictionary case, the data is held in the value field.
471 ASSERT(lookup_type_ == DICTIONARY_TYPE);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000472 return holder()->GetNormalizedProperty(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000473 }
474
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000475 Object* GetValueFromMap(Map* map) const {
476 ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +0000477 ASSERT(number_ < map->NumberOfOwnDescriptors());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000478 return map->instance_descriptors()->GetValue(number_);
479 }
480
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000481 int GetFieldIndexFromMap(Map* map) const {
482 ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
483 ASSERT(number_ < map->NumberOfOwnDescriptors());
484 return map->instance_descriptors()->GetFieldIndex(number_);
485 }
486
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000487 void Iterate(ObjectVisitor* visitor);
488
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000489 private:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000490 Isolate* isolate_;
491 LookupResult* next_;
492
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000493 // Where did we find the result;
494 enum {
495 NOT_FOUND,
496 DESCRIPTOR_TYPE,
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000497 TRANSITION_TYPE,
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000498 DICTIONARY_TYPE,
499 HANDLER_TYPE,
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +0000500 INTERCEPTOR_TYPE
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000501 } lookup_type_;
502
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000503 JSReceiver* holder_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000504 int number_;
505 bool cacheable_;
506 PropertyDetails details_;
507};
508
509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000510} } // namespace v8::internal
511
512#endif // V8_PROPERTY_H_