blob: a9d8b09354a6a89a86350fed6cba4905e5e7afa7 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_PROPERTY_H_
6#define V8_PROPERTY_H_
7
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008#include <iosfwd>
9
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/factory.h"
11#include "src/field-index.h"
12#include "src/field-index-inl.h"
13#include "src/isolate.h"
14#include "src/types.h"
Ben Murdoch257744e2011-11-30 15:57:28 +000015
Steve Blocka7e24c12009-10-30 11:49:00 +000016namespace v8 {
17namespace internal {
18
Steve Blocka7e24c12009-10-30 11:49:00 +000019// Abstraction for elements in instance-descriptor arrays.
20//
21// Each descriptor has a key, property attributes, property type,
22// property index (in the actual instance-descriptor array) and
23// optionally a piece of data.
Steve Blocka7e24c12009-10-30 11:49:00 +000024class Descriptor BASE_EMBEDDED {
25 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026 void KeyToUniqueName() {
27 if (!key_->IsUniqueName()) {
28 key_ = key_->GetIsolate()->factory()->InternalizeString(
29 Handle<String>::cast(key_));
Steve Blocka7e24c12009-10-30 11:49:00 +000030 }
Steve Blocka7e24c12009-10-30 11:49:00 +000031 }
32
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033 Handle<Name> GetKey() const { return key_; }
34 Handle<Object> GetValue() const { return value_; }
35 PropertyDetails GetDetails() const { return details_; }
Steve Blocka7e24c12009-10-30 11:49:00 +000036
Ben Murdochb8a8cc12014-11-26 15:28:44 +000037 void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +010038
Steve Blocka7e24c12009-10-30 11:49:00 +000039 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040 Handle<Name> key_;
41 Handle<Object> value_;
Steve Blocka7e24c12009-10-30 11:49:00 +000042 PropertyDetails details_;
43
44 protected:
45 Descriptor() : details_(Smi::FromInt(0)) {}
46
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047 void Init(Handle<Name> key, Handle<Object> value, PropertyDetails details) {
Steve Blocka7e24c12009-10-30 11:49:00 +000048 key_ = key;
49 value_ = value;
50 details_ = details;
51 }
52
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053 Descriptor(Handle<Name> key, Handle<Object> value, PropertyDetails details)
Steve Blocka7e24c12009-10-30 11:49:00 +000054 : key_(key),
55 value_(value),
56 details_(details) { }
57
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058 Descriptor(Handle<Name> key,
59 Handle<Object> value,
Steve Blocka7e24c12009-10-30 11:49:00 +000060 PropertyAttributes attributes,
61 PropertyType type,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062 Representation representation,
63 int field_index = 0)
Steve Blocka7e24c12009-10-30 11:49:00 +000064 : key_(key),
65 value_(value),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066 details_(attributes, type, representation, field_index) { }
Steve Blocka7e24c12009-10-30 11:49:00 +000067
68 friend class DescriptorArray;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 friend class Map;
Steve Blocka7e24c12009-10-30 11:49:00 +000070};
71
72
Emily Bernierd0a1eb72015-03-24 16:35:39 -040073std::ostream& operator<<(std::ostream& os, const Descriptor& d);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074
75
76class FieldDescriptor FINAL : public Descriptor {
Steve Blocka7e24c12009-10-30 11:49:00 +000077 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 FieldDescriptor(Handle<Name> key,
Steve Blocka7e24c12009-10-30 11:49:00 +000079 int field_index,
80 PropertyAttributes attributes,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 Representation representation)
82 : Descriptor(key, HeapType::Any(key->GetIsolate()), attributes,
83 FIELD, representation, field_index) {}
84 FieldDescriptor(Handle<Name> key,
85 int field_index,
86 Handle<HeapType> field_type,
87 PropertyAttributes attributes,
88 Representation representation)
89 : Descriptor(key, field_type, attributes, FIELD,
90 representation, field_index) { }
Steve Blocka7e24c12009-10-30 11:49:00 +000091};
92
93
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094class ConstantDescriptor FINAL : public Descriptor {
Steve Blocka7e24c12009-10-30 11:49:00 +000095 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096 ConstantDescriptor(Handle<Name> key,
97 Handle<Object> value,
98 PropertyAttributes attributes)
99 : Descriptor(key, value, attributes, CONSTANT,
100 value->OptimalRepresentation()) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000101};
102
103
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000104class CallbacksDescriptor FINAL : public Descriptor {
Steve Blocka7e24c12009-10-30 11:49:00 +0000105 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106 CallbacksDescriptor(Handle<Name> key,
107 Handle<Object> foreign,
108 PropertyAttributes attributes)
109 : Descriptor(key, foreign, attributes, CALLBACKS,
110 Representation::Tagged()) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000111};
112
113
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000114class LookupResult FINAL BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000115 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100116 explicit LookupResult(Isolate* isolate)
117 : isolate_(isolate),
118 next_(isolate->top_lookup_result()),
119 lookup_type_(NOT_FOUND),
120 holder_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121 transition_(NULL),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400122 details_(NONE, FIELD, Representation::None()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123 isolate->set_top_lookup_result(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100124 }
125
126 ~LookupResult() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 DCHECK(isolate()->top_lookup_result() == this);
128 isolate()->set_top_lookup_result(next_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100129 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000130
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000131 Isolate* isolate() const { return isolate_; }
132
Steve Blocka7e24c12009-10-30 11:49:00 +0000133 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
134 lookup_type_ = DESCRIPTOR_TYPE;
135 holder_ = holder;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136 transition_ = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000137 details_ = details;
138 number_ = number;
139 }
140
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141 void TransitionResult(JSObject* holder, Map* target) {
142 lookup_type_ = TRANSITION_TYPE;
143 number_ = target->LastAdded();
144 details_ = target->instance_descriptors()->GetDetails(number_);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100145 holder_ = holder;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146 transition_ = target;
Steve Blocka7e24c12009-10-30 11:49:00 +0000147 }
148
149 void NotFound() {
150 lookup_type_ = NOT_FOUND;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400151 details_ = PropertyDetails(NONE, FIELD, 0);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100152 holder_ = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153 transition_ = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000154 }
155
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156 Representation representation() const {
157 DCHECK(IsFound());
158 return details_.representation();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100159 }
160
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000161 // Property callbacks does not include transitions to callbacks.
162 bool IsPropertyCallbacks() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163 return !IsTransition() && details_.type() == CALLBACKS;
Steve Blocka7e24c12009-10-30 11:49:00 +0000164 }
165
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000166 bool IsReadOnly() const {
167 DCHECK(IsFound());
168 return details_.IsReadOnly();
Steve Blocka7e24c12009-10-30 11:49:00 +0000169 }
170
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171 bool IsField() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == FIELD;
Steve Blocka7e24c12009-10-30 11:49:00 +0000173 }
174
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175 bool IsConstant() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176 return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == CONSTANT;
Steve Blocka7e24c12009-10-30 11:49:00 +0000177 }
178
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179 bool IsConfigurable() const { return details_.IsConfigurable(); }
180 bool IsFound() const { return lookup_type_ != NOT_FOUND; }
181 bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000182
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100183 // Is the result is a property excluding transitions and the null descriptor?
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000184 bool IsProperty() const {
185 return IsFound() && !IsTransition();
Andrei Popescu402d9372010-02-26 13:31:12 +0000186 }
187
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000188 Map* GetTransitionTarget() const {
189 DCHECK(IsTransition());
190 return transition_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000191 }
192
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000193 bool IsTransitionToField() const {
194 return IsTransition() && details_.type() == FIELD;
Steve Blocka7e24c12009-10-30 11:49:00 +0000195 }
196
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000197 int GetLocalFieldIndexFromMap(Map* map) const {
198 return GetFieldIndexFromMap(map) - map->inobject_properties();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100199 }
200
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000201 Object* GetConstantFromMap(Map* map) const {
202 DCHECK(details_.type() == CONSTANT);
203 return GetValueFromMap(map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000204 }
205
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000206 Object* GetValueFromMap(Map* map) const {
207 DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
208 lookup_type_ == TRANSITION_TYPE);
209 DCHECK(number_ < map->NumberOfOwnDescriptors());
210 return map->instance_descriptors()->GetValue(number_);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100211 }
212
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213 int GetFieldIndexFromMap(Map* map) const {
214 DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
215 lookup_type_ == TRANSITION_TYPE);
216 DCHECK(number_ < map->NumberOfOwnDescriptors());
217 return map->instance_descriptors()->GetFieldIndex(number_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000218 }
219
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220 HeapType* GetFieldTypeFromMap(Map* map) const {
221 DCHECK_NE(NOT_FOUND, lookup_type_);
222 DCHECK(number_ < map->NumberOfOwnDescriptors());
223 return map->instance_descriptors()->GetFieldType(number_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000224 }
225
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226 Map* GetFieldOwnerFromMap(Map* map) const {
227 DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
228 lookup_type_ == TRANSITION_TYPE);
229 DCHECK(number_ < map->NumberOfOwnDescriptors());
230 return map->FindFieldOwner(number_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000231 }
232
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100233 void Iterate(ObjectVisitor* visitor);
234
Steve Blocka7e24c12009-10-30 11:49:00 +0000235 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100236 Isolate* isolate_;
237 LookupResult* next_;
238
Ben Murdoch257744e2011-11-30 15:57:28 +0000239 // Where did we find the result;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000240 enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000241
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100242 JSReceiver* holder_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243 Map* transition_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000244 int number_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000245 PropertyDetails details_;
246};
247
248
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400249std::ostream& operator<<(std::ostream& os, const LookupResult& r);
Steve Blocka7e24c12009-10-30 11:49:00 +0000250} } // namespace v8::internal
251
252#endif // V8_PROPERTY_H_