| 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 |