| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 4111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4122 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); | 4122 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); |
| 4123 return value; | 4123 return value; |
| 4124 } | 4124 } |
| 4125 | 4125 |
| 4126 | 4126 |
| 4127 Maybe<bool> Object::SetPropertyInternal(LookupIterator* it, | 4127 Maybe<bool> Object::SetPropertyInternal(LookupIterator* it, |
| 4128 Handle<Object> value, | 4128 Handle<Object> value, |
| 4129 LanguageMode language_mode, | 4129 LanguageMode language_mode, |
| 4130 StoreFromKeyed store_mode, | 4130 StoreFromKeyed store_mode, |
| 4131 bool* found) { | 4131 bool* found) { |
| 4132 it->UpdateProtector(); | 4132 DCHECK(it->IsFound()); |
| 4133 ShouldThrow should_throw = | 4133 ShouldThrow should_throw = |
| 4134 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 4134 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 4135 | 4135 |
| 4136 // Make sure that the top context does not change when doing callbacks or | 4136 // Make sure that the top context does not change when doing callbacks or |
| 4137 // interceptor calls. | 4137 // interceptor calls. |
| 4138 AssertNoContextChange ncc(it->isolate()); | 4138 AssertNoContextChange ncc(it->isolate()); |
| 4139 | 4139 |
| 4140 for (; it->IsFound(); it->Next()) { | 4140 do { |
| 4141 switch (it->state()) { | 4141 switch (it->state()) { |
| 4142 case LookupIterator::NOT_FOUND: | 4142 case LookupIterator::NOT_FOUND: |
| 4143 UNREACHABLE(); | 4143 UNREACHABLE(); |
| 4144 | 4144 |
| 4145 case LookupIterator::ACCESS_CHECK: | 4145 case LookupIterator::ACCESS_CHECK: |
| 4146 if (it->HasAccess()) break; | 4146 if (it->HasAccess()) break; |
| 4147 // Check whether it makes sense to reuse the lookup iterator. Here it | 4147 // Check whether it makes sense to reuse the lookup iterator. Here it |
| 4148 // might still call into setters up the prototype chain. | 4148 // might still call into setters up the prototype chain. |
| 4149 return JSObject::SetPropertyWithFailedAccessCheck(it, value, | 4149 return JSObject::SetPropertyWithFailedAccessCheck(it, value, |
| 4150 should_throw); | 4150 should_throw); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4193 return WriteToReadOnlyProperty(it, value, should_throw); | 4193 return WriteToReadOnlyProperty(it, value, should_throw); |
| 4194 } | 4194 } |
| 4195 if (it->HolderIsReceiverOrHiddenPrototype()) { | 4195 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 4196 return SetDataProperty(it, value); | 4196 return SetDataProperty(it, value); |
| 4197 } | 4197 } |
| 4198 // Fall through. | 4198 // Fall through. |
| 4199 case LookupIterator::TRANSITION: | 4199 case LookupIterator::TRANSITION: |
| 4200 *found = false; | 4200 *found = false; |
| 4201 return Nothing<bool>(); | 4201 return Nothing<bool>(); |
| 4202 } | 4202 } |
| 4203 } | 4203 it->Next(); |
| 4204 } while (it->IsFound()); |
| 4204 | 4205 |
| 4205 *found = false; | 4206 *found = false; |
| 4206 return Nothing<bool>(); | 4207 return Nothing<bool>(); |
| 4207 } | 4208 } |
| 4208 | 4209 |
| 4209 | 4210 |
| 4210 Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value, | 4211 Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value, |
| 4211 LanguageMode language_mode, | 4212 LanguageMode language_mode, |
| 4212 StoreFromKeyed store_mode) { | 4213 StoreFromKeyed store_mode) { |
| 4213 bool found = true; | 4214 it->UpdateProtector(); |
| 4214 Maybe<bool> result = | 4215 if (it->IsFound()) { |
| 4215 SetPropertyInternal(it, value, language_mode, store_mode, &found); | 4216 bool found = true; |
| 4216 if (found) return result; | 4217 Maybe<bool> result = |
| 4218 SetPropertyInternal(it, value, language_mode, store_mode, &found); |
| 4219 if (found) return result; |
| 4220 } |
| 4217 | 4221 |
| 4218 // If the receiver is the JSGlobalObject, the store was contextual. In case | 4222 // If the receiver is the JSGlobalObject, the store was contextual. In case |
| 4219 // the property did not exist yet on the global object itself, we have to | 4223 // the property did not exist yet on the global object itself, we have to |
| 4220 // throw a reference error in strict mode. In sloppy mode, we continue. | 4224 // throw a reference error in strict mode. In sloppy mode, we continue. |
| 4221 if (is_strict(language_mode) && it->GetReceiver()->IsJSGlobalObject()) { | 4225 if (is_strict(language_mode) && it->GetReceiver()->IsJSGlobalObject()) { |
| 4222 it->isolate()->Throw(*it->isolate()->factory()->NewReferenceError( | 4226 it->isolate()->Throw(*it->isolate()->factory()->NewReferenceError( |
| 4223 MessageTemplate::kNotDefined, it->name())); | 4227 MessageTemplate::kNotDefined, it->name())); |
| 4224 return Nothing<bool>(); | 4228 return Nothing<bool>(); |
| 4225 } | 4229 } |
| 4226 | 4230 |
| 4227 ShouldThrow should_throw = | 4231 ShouldThrow should_throw = |
| 4228 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 4232 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 4229 return AddDataProperty(it, value, NONE, should_throw, store_mode); | 4233 return AddDataProperty(it, value, NONE, should_throw, store_mode); |
| 4230 } | 4234 } |
| 4231 | 4235 |
| 4232 | 4236 |
| 4233 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, | 4237 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, |
| 4234 LanguageMode language_mode, | 4238 LanguageMode language_mode, |
| 4235 StoreFromKeyed store_mode) { | 4239 StoreFromKeyed store_mode) { |
| 4236 Isolate* isolate = it->isolate(); | 4240 Isolate* isolate = it->isolate(); |
| 4237 | 4241 |
| 4238 bool found = true; | 4242 it->UpdateProtector(); |
| 4239 Maybe<bool> result = | 4243 if (it->IsFound()) { |
| 4240 SetPropertyInternal(it, value, language_mode, store_mode, &found); | 4244 bool found = true; |
| 4241 if (found) return result; | 4245 Maybe<bool> result = |
| 4246 SetPropertyInternal(it, value, language_mode, store_mode, &found); |
| 4247 if (found) return result; |
| 4248 } |
| 4242 | 4249 |
| 4243 // The property either doesn't exist on the holder or exists there as a data | 4250 // The property either doesn't exist on the holder or exists there as a data |
| 4244 // property. | 4251 // property. |
| 4245 | 4252 |
| 4246 ShouldThrow should_throw = | 4253 ShouldThrow should_throw = |
| 4247 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 4254 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 4248 | 4255 |
| 4249 if (!it->GetReceiver()->IsJSReceiver()) { | 4256 if (!it->GetReceiver()->IsJSReceiver()) { |
| 4250 return WriteToReadOnlyProperty(it, value, should_throw); | 4257 return WriteToReadOnlyProperty(it, value, should_throw); |
| 4251 } | 4258 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4306 return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(), | 4313 return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(), |
| 4307 &value_desc, should_throw); | 4314 &value_desc, should_throw); |
| 4308 } | 4315 } |
| 4309 | 4316 |
| 4310 case LookupIterator::NOT_FOUND: | 4317 case LookupIterator::NOT_FOUND: |
| 4311 case LookupIterator::TRANSITION: | 4318 case LookupIterator::TRANSITION: |
| 4312 UNREACHABLE(); | 4319 UNREACHABLE(); |
| 4313 } | 4320 } |
| 4314 } | 4321 } |
| 4315 | 4322 |
| 4316 return JSObject::AddDataProperty(&own_lookup, value, NONE, should_throw, | 4323 return AddDataProperty(&own_lookup, value, NONE, should_throw, store_mode); |
| 4317 store_mode); | |
| 4318 } | 4324 } |
| 4319 | 4325 |
| 4320 MaybeHandle<Object> Object::ReadAbsentProperty(LookupIterator* it) { | 4326 MaybeHandle<Object> Object::ReadAbsentProperty(LookupIterator* it) { |
| 4321 return it->isolate()->factory()->undefined_value(); | 4327 return it->isolate()->factory()->undefined_value(); |
| 4322 } | 4328 } |
| 4323 | 4329 |
| 4324 MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate, | 4330 MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate, |
| 4325 Handle<Object> receiver, | 4331 Handle<Object> receiver, |
| 4326 Handle<Object> name) { | 4332 Handle<Object> name) { |
| 4327 return isolate->factory()->undefined_value(); | 4333 return isolate->factory()->undefined_value(); |
| (...skipping 4038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8366 Handle<FixedArray> array, int length) { | 8372 Handle<FixedArray> array, int length) { |
| 8367 DCHECK_LE(length, array->length()); | 8373 DCHECK_LE(length, array->length()); |
| 8368 if (array->length() == length) return array; | 8374 if (array->length() == length) return array; |
| 8369 return array->GetIsolate()->factory()->CopyFixedArrayUpTo(array, length); | 8375 return array->GetIsolate()->factory()->CopyFixedArrayUpTo(array, length); |
| 8370 } | 8376 } |
| 8371 | 8377 |
| 8372 bool Map::OnlyHasSimpleProperties() { | 8378 bool Map::OnlyHasSimpleProperties() { |
| 8373 // Wrapped string elements aren't explicitly stored in the elements backing | 8379 // Wrapped string elements aren't explicitly stored in the elements backing |
| 8374 // store, but are loaded indirectly from the underlying string. | 8380 // store, but are loaded indirectly from the underlying string. |
| 8375 return !IsStringWrapperElementsKind(elements_kind()) && | 8381 return !IsStringWrapperElementsKind(elements_kind()) && |
| 8376 !is_access_check_needed() && !has_named_interceptor() && | 8382 instance_type() > LAST_SPECIAL_RECEIVER_TYPE && |
| 8377 !has_indexed_interceptor() && !has_hidden_prototype() && | 8383 !has_hidden_prototype() && !is_dictionary_map(); |
| 8378 !is_dictionary_map(); | |
| 8379 } | 8384 } |
| 8380 | 8385 |
| 8381 namespace { | 8386 namespace { |
| 8382 | 8387 |
| 8383 Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate, | 8388 Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate, |
| 8384 Handle<JSObject> object) { | 8389 Handle<JSObject> object) { |
| 8385 Handle<Map> map(object->map()); | 8390 Handle<Map> map(object->map()); |
| 8386 bool cache_enum_length = map->OnlyHasSimpleProperties(); | 8391 bool cache_enum_length = map->OnlyHasSimpleProperties(); |
| 8387 | 8392 |
| 8388 Handle<DescriptorArray> descs = | 8393 Handle<DescriptorArray> descs = |
| (...skipping 11375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19764 if (cell->value() != *new_value) { | 19769 if (cell->value() != *new_value) { |
| 19765 cell->set_value(*new_value); | 19770 cell->set_value(*new_value); |
| 19766 Isolate* isolate = cell->GetIsolate(); | 19771 Isolate* isolate = cell->GetIsolate(); |
| 19767 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19772 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19768 isolate, DependentCode::kPropertyCellChangedGroup); | 19773 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19769 } | 19774 } |
| 19770 } | 19775 } |
| 19771 | 19776 |
| 19772 } // namespace internal | 19777 } // namespace internal |
| 19773 } // namespace v8 | 19778 } // namespace v8 |
| OLD | NEW |