OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/lookup.h" | 8 #include "src/lookup.h" |
9 #include "src/lookup-inl.h" | 9 #include "src/lookup-inl.h" |
10 | 10 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // Reload property information. | 119 // Reload property information. |
120 if (holder_map_->is_dictionary_map()) { | 120 if (holder_map_->is_dictionary_map()) { |
121 property_encoding_ = DICTIONARY; | 121 property_encoding_ = DICTIONARY; |
122 } else { | 122 } else { |
123 property_encoding_ = DESCRIPTOR; | 123 property_encoding_ = DESCRIPTOR; |
124 } | 124 } |
125 CHECK(HasProperty()); | 125 CHECK(HasProperty()); |
126 } | 126 } |
127 | 127 |
128 | 128 |
| 129 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, |
| 130 PropertyAttributes attributes) { |
| 131 DCHECK(has_property_); |
| 132 DCHECK(HolderIsReceiverOrHiddenPrototype()); |
| 133 Handle<JSObject> holder = GetHolder<JSObject>(); |
| 134 if (property_encoding_ != DICTIONARY) { |
| 135 holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(), |
| 136 attributes); |
| 137 JSObject::MigrateToMap(holder, holder_map_); |
| 138 } |
| 139 |
| 140 // Reload property information and update the descriptor if in dictionary |
| 141 // mode. |
| 142 if (holder_map_->is_dictionary_map()) { |
| 143 property_encoding_ = DICTIONARY; |
| 144 PropertyDetails details(attributes, NORMAL, 0); |
| 145 JSObject::SetNormalizedProperty(holder, name(), value, details); |
| 146 } else { |
| 147 property_encoding_ = DESCRIPTOR; |
| 148 } |
| 149 |
| 150 CHECK(HasProperty()); |
| 151 } |
| 152 |
| 153 |
129 void LookupIterator::TransitionToDataProperty( | 154 void LookupIterator::TransitionToDataProperty( |
130 Handle<Object> value, PropertyAttributes attributes, | 155 Handle<Object> value, PropertyAttributes attributes, |
131 Object::StoreFromKeyed store_mode) { | 156 Object::StoreFromKeyed store_mode) { |
132 DCHECK(!has_property_ || !HolderIsReceiverOrHiddenPrototype()); | 157 DCHECK(!has_property_ || !HolderIsReceiverOrHiddenPrototype()); |
133 | 158 |
134 // Can only be called when the receiver is a JSObject. JSProxy has to be | 159 // Can only be called when the receiver is a JSObject. JSProxy has to be |
135 // handled via a trap. Adding properties to primitive values is not | 160 // handled via a trap. Adding properties to primitive values is not |
136 // observable. | 161 // observable. |
137 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); | 162 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); |
138 | 163 |
139 // Properties have to be added to context extension objects through | |
140 // SetOwnPropertyIgnoreAttributes. | |
141 DCHECK(!receiver->IsJSContextExtensionObject()); | |
142 | |
143 if (receiver->IsJSGlobalProxy()) { | 164 if (receiver->IsJSGlobalProxy()) { |
144 PrototypeIterator iter(isolate(), receiver); | 165 PrototypeIterator iter(isolate(), receiver); |
145 receiver = | 166 receiver = |
146 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); | 167 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); |
147 } | 168 } |
148 | 169 |
149 maybe_holder_ = receiver; | 170 maybe_holder_ = receiver; |
150 holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_, | 171 holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_, |
151 value, attributes, store_mode); | 172 value, attributes, store_mode); |
152 JSObject::MigrateToMap(receiver, holder_map_); | 173 JSObject::MigrateToMap(receiver, holder_map_); |
153 | 174 |
154 // Reload the information. | 175 // Reload the information. |
155 state_ = NOT_FOUND; | 176 state_ = NOT_FOUND; |
156 configuration_ = CHECK_OWN_REAL; | 177 configuration_ = CHECK_OWN_REAL; |
157 state_ = LookupInHolder(*holder_map_); | 178 state_ = LookupInHolder(*holder_map_); |
158 DCHECK(IsFound()); | 179 DCHECK(IsFound()); |
159 HasProperty(); | 180 HasProperty(); |
160 } | 181 } |
161 | 182 |
162 | 183 |
163 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { | 184 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { |
164 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); | 185 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); |
| 186 // Optimization that only works if configuration_ is not mutable. |
| 187 if (!check_derived()) return true; |
165 DisallowHeapAllocation no_gc; | 188 DisallowHeapAllocation no_gc; |
166 Handle<Object> receiver = GetReceiver(); | 189 Handle<Object> receiver = GetReceiver(); |
167 if (!receiver->IsJSReceiver()) return false; | 190 if (!receiver->IsJSReceiver()) return false; |
168 Object* current = *receiver; | 191 Object* current = *receiver; |
169 JSReceiver* holder = *maybe_holder_.ToHandleChecked(); | 192 JSReceiver* holder = *maybe_holder_.ToHandleChecked(); |
170 // JSProxy do not occur as hidden prototypes. | 193 // JSProxy do not occur as hidden prototypes. |
171 if (current->IsJSProxy()) { | 194 if (current->IsJSProxy()) { |
172 return JSReceiver::cast(current) == holder; | 195 return JSReceiver::cast(current) == holder; |
173 } | 196 } |
174 PrototypeIterator iter(isolate(), current, | 197 PrototypeIterator iter(isolate(), current, |
175 PrototypeIterator::START_AT_RECEIVER); | 198 PrototypeIterator::START_AT_RECEIVER); |
176 do { | 199 do { |
177 if (JSReceiver::cast(iter.GetCurrent()) == holder) return true; | 200 if (JSReceiver::cast(iter.GetCurrent()) == holder) return true; |
178 DCHECK(!current->IsJSProxy()); | 201 DCHECK(!current->IsJSProxy()); |
179 iter.Advance(); | 202 iter.Advance(); |
180 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); | 203 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); |
181 return false; | 204 return false; |
182 } | 205 } |
183 | 206 |
184 | 207 |
| 208 bool LookupIterator::HolderIsNonGlobalHiddenPrototype() const { |
| 209 if (!HolderIsReceiverOrHiddenPrototype()) return false; |
| 210 Handle<Object> receiver = GetReceiver(); |
| 211 Handle<JSReceiver> holder = GetHolder<JSReceiver>(); |
| 212 if (receiver.is_identical_to(holder)) return false; |
| 213 if (receiver->IsJSGlobalProxy()) return !holder->IsJSGlobalObject(); |
| 214 return true; |
| 215 } |
| 216 |
| 217 |
185 Handle<Object> LookupIterator::FetchValue() const { | 218 Handle<Object> LookupIterator::FetchValue() const { |
186 Object* result = NULL; | 219 Object* result = NULL; |
187 Handle<JSObject> holder = GetHolder<JSObject>(); | 220 Handle<JSObject> holder = GetHolder<JSObject>(); |
188 switch (property_encoding_) { | 221 switch (property_encoding_) { |
189 case DICTIONARY: | 222 case DICTIONARY: |
190 result = holder->property_dictionary()->ValueAt(number_); | 223 result = holder->property_dictionary()->ValueAt(number_); |
191 if (holder->IsGlobalObject()) { | 224 if (holder->IsGlobalObject()) { |
192 result = PropertyCell::cast(result)->value(); | 225 result = PropertyCell::cast(result)->value(); |
193 } | 226 } |
194 break; | 227 break; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); | 299 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); |
267 } | 300 } |
268 } | 301 } |
269 | 302 |
270 | 303 |
271 void LookupIterator::InternalizeName() { | 304 void LookupIterator::InternalizeName() { |
272 if (name_->IsUniqueName()) return; | 305 if (name_->IsUniqueName()) return; |
273 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); | 306 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); |
274 } | 307 } |
275 } } // namespace v8::internal | 308 } } // namespace v8::internal |
OLD | NEW |