OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 6006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6017 bool JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, | 6017 bool JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, |
6018 Handle<JSObject> object, | 6018 Handle<JSObject> object, |
6019 Handle<Object> key, | 6019 Handle<Object> key, |
6020 PropertyDescriptor* desc, | 6020 PropertyDescriptor* desc, |
6021 ShouldThrow should_throw) { | 6021 ShouldThrow should_throw) { |
6022 bool success = false; | 6022 bool success = false; |
6023 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey... | 6023 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey... |
6024 LookupIterator it = LookupIterator::PropertyOrElement( | 6024 LookupIterator it = LookupIterator::PropertyOrElement( |
6025 isolate, object, key, &success, LookupIterator::HIDDEN); | 6025 isolate, object, key, &success, LookupIterator::HIDDEN); |
6026 DCHECK(success); // ...so creating a LookupIterator can't fail. | 6026 DCHECK(success); // ...so creating a LookupIterator can't fail. |
| 6027 |
| 6028 // Deal with access checks first. |
| 6029 if (it.state() == LookupIterator::ACCESS_CHECK) { |
| 6030 if (!it.HasAccess()) { |
| 6031 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>()); |
| 6032 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false); |
| 6033 return false; |
| 6034 } |
| 6035 it.Next(); |
| 6036 } |
| 6037 |
6027 return OrdinaryDefineOwnProperty(&it, desc, should_throw); | 6038 return OrdinaryDefineOwnProperty(&it, desc, should_throw); |
6028 } | 6039 } |
6029 | 6040 |
6030 | 6041 |
6031 // ES6 9.1.6.1 | 6042 // ES6 9.1.6.1 |
6032 // static | 6043 // static |
6033 bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, | 6044 bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, |
6034 PropertyDescriptor* desc, | 6045 PropertyDescriptor* desc, |
6035 ShouldThrow should_throw) { | 6046 ShouldThrow should_throw) { |
6036 Isolate* isolate = it->isolate(); | 6047 Isolate* isolate = it->isolate(); |
(...skipping 19 matching lines...) Expand all Loading... |
6056 // 2. If current is undefined, then | 6067 // 2. If current is undefined, then |
6057 if (current.is_empty()) { | 6068 if (current.is_empty()) { |
6058 // 2a. If extensible is false, return false. | 6069 // 2a. If extensible is false, return false. |
6059 if (!extensible) { | 6070 if (!extensible) { |
6060 if (should_throw == THROW_ON_ERROR) { | 6071 if (should_throw == THROW_ON_ERROR) { |
6061 isolate->Throw(*isolate->factory()->NewTypeError( | 6072 isolate->Throw(*isolate->factory()->NewTypeError( |
6062 MessageTemplate::kDefineDisallowed, it->GetName())); | 6073 MessageTemplate::kDefineDisallowed, it->GetName())); |
6063 } | 6074 } |
6064 return false; | 6075 return false; |
6065 } | 6076 } |
| 6077 // We have to use a fresh LookupIterator to handle interceptors properly. |
| 6078 LookupIterator lookup_for_store = |
| 6079 it->IsElement() ? LookupIterator(isolate, it->GetReceiver(), |
| 6080 it->index(), LookupIterator::HIDDEN) |
| 6081 : LookupIterator(it->GetReceiver(), it->name(), |
| 6082 LookupIterator::HIDDEN); |
| 6083 |
6066 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then: | 6084 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then: |
6067 // (This is equivalent to !IsAccessorDescriptor(desc).) | 6085 // (This is equivalent to !IsAccessorDescriptor(desc).) |
6068 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) == | 6086 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) == |
6069 !desc_is_accessor_descriptor); | 6087 !desc_is_accessor_descriptor); |
6070 if (!desc_is_accessor_descriptor) { | 6088 if (!desc_is_accessor_descriptor) { |
6071 // 2c i. If O is not undefined, create an own data property named P of | 6089 // 2c i. If O is not undefined, create an own data property named P of |
6072 // object O whose [[Value]], [[Writable]], [[Enumerable]] and | 6090 // object O whose [[Value]], [[Writable]], [[Enumerable]] and |
6073 // [[Configurable]] attribute values are described by Desc. If the value | 6091 // [[Configurable]] attribute values are described by Desc. If the value |
6074 // of an attribute field of Desc is absent, the attribute of the newly | 6092 // of an attribute field of Desc is absent, the attribute of the newly |
6075 // created property is set to its default value. | 6093 // created property is set to its default value. |
6076 if (!o->IsUndefined()) { | 6094 if (!o->IsUndefined()) { |
6077 if (!desc->has_writable()) desc->set_writable(false); | 6095 if (!desc->has_writable()) desc->set_writable(false); |
6078 if (!desc->has_enumerable()) desc->set_enumerable(false); | 6096 if (!desc->has_enumerable()) desc->set_enumerable(false); |
6079 if (!desc->has_configurable()) desc->set_configurable(false); | 6097 if (!desc->has_configurable()) desc->set_configurable(false); |
6080 Handle<Object> value( | 6098 Handle<Object> value( |
6081 desc->has_value() | 6099 desc->has_value() |
6082 ? desc->value() | 6100 ? desc->value() |
6083 : Handle<Object>::cast(isolate->factory()->undefined_value())); | 6101 : Handle<Object>::cast(isolate->factory()->undefined_value())); |
6084 MaybeHandle<Object> result = | 6102 MaybeHandle<Object> result = |
6085 JSObject::DefineOwnPropertyIgnoreAttributes(it, value, | 6103 JSObject::DefineOwnPropertyIgnoreAttributes( |
6086 desc->ToAttributes()); | 6104 &lookup_for_store, value, desc->ToAttributes(), |
| 6105 JSObject::DONT_FORCE_FIELD); |
6087 if (result.is_null()) return false; | 6106 if (result.is_null()) return false; |
6088 } | 6107 } |
6089 } else { | 6108 } else { |
6090 // 2d. Else Desc must be an accessor Property Descriptor, | 6109 // 2d. Else Desc must be an accessor Property Descriptor, |
6091 DCHECK(desc_is_accessor_descriptor); | 6110 DCHECK(desc_is_accessor_descriptor); |
6092 // 2d i. If O is not undefined, create an own accessor property named P | 6111 // 2d i. If O is not undefined, create an own accessor property named P |
6093 // of object O whose [[Get]], [[Set]], [[Enumerable]] and | 6112 // of object O whose [[Get]], [[Set]], [[Enumerable]] and |
6094 // [[Configurable]] attribute values are described by Desc. If the value | 6113 // [[Configurable]] attribute values are described by Desc. If the value |
6095 // of an attribute field of Desc is absent, the attribute of the newly | 6114 // of an attribute field of Desc is absent, the attribute of the newly |
6096 // created property is set to its default value. | 6115 // created property is set to its default value. |
6097 if (!o->IsUndefined()) { | 6116 if (!o->IsUndefined()) { |
6098 if (!desc->has_enumerable()) desc->set_enumerable(false); | 6117 if (!desc->has_enumerable()) desc->set_enumerable(false); |
6099 if (!desc->has_configurable()) desc->set_configurable(false); | 6118 if (!desc->has_configurable()) desc->set_configurable(false); |
6100 Handle<Object> getter( | 6119 Handle<Object> getter( |
6101 desc->has_get() | 6120 desc->has_get() |
6102 ? desc->get() | 6121 ? desc->get() |
6103 : Handle<Object>::cast(isolate->factory()->undefined_value())); | 6122 : Handle<Object>::cast(isolate->factory()->undefined_value())); |
6104 Handle<Object> setter( | 6123 Handle<Object> setter( |
6105 desc->has_set() | 6124 desc->has_set() |
6106 ? desc->set() | 6125 ? desc->set() |
6107 : Handle<Object>::cast(isolate->factory()->undefined_value())); | 6126 : Handle<Object>::cast(isolate->factory()->undefined_value())); |
6108 MaybeHandle<Object> result = | 6127 MaybeHandle<Object> result = JSObject::DefineAccessor( |
6109 JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes()); | 6128 &lookup_for_store, getter, setter, desc->ToAttributes()); |
6110 if (result.is_null()) return false; | 6129 if (result.is_null()) return false; |
6111 } | 6130 } |
6112 } | 6131 } |
6113 // 2e. Return true. | 6132 // 2e. Return true. |
6114 return true; | 6133 return true; |
6115 } | 6134 } |
6116 // 3. Return true, if every field in Desc is absent. | 6135 // 3. Return true, if every field in Desc is absent. |
6117 // 4. Return true, if every field in Desc also occurs in current and the | 6136 // 4. Return true, if every field in Desc also occurs in current and the |
6118 // value of every field in Desc is the same value as the corresponding field | 6137 // value of every field in Desc is the same value as the corresponding field |
6119 // in current when compared using the SameValue algorithm. | 6138 // in current when compared using the SameValue algorithm. |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6508 OrdinaryDefineOwnProperty(isolate, a, isolate->factory()->length_string(), | 6527 OrdinaryDefineOwnProperty(isolate, a, isolate->factory()->length_string(), |
6509 &readonly, should_throw); | 6528 &readonly, should_throw); |
6510 } | 6529 } |
6511 uint32_t actual_new_len = 0; | 6530 uint32_t actual_new_len = 0; |
6512 CHECK(a->length()->ToArrayLength(&actual_new_len)); | 6531 CHECK(a->length()->ToArrayLength(&actual_new_len)); |
6513 // Steps 19d-v, 21. Return false if there were non-deletable elements. | 6532 // Steps 19d-v, 21. Return false if there were non-deletable elements. |
6514 success = actual_new_len == new_len; | 6533 success = actual_new_len == new_len; |
6515 if (!success && should_throw == THROW_ON_ERROR) { | 6534 if (!success && should_throw == THROW_ON_ERROR) { |
6516 isolate->Throw(*isolate->factory()->NewTypeError( | 6535 isolate->Throw(*isolate->factory()->NewTypeError( |
6517 MessageTemplate::kStrictDeleteProperty, | 6536 MessageTemplate::kStrictDeleteProperty, |
6518 isolate->factory()->NewNumberFromUint(actual_new_len - 1))); | 6537 isolate->factory()->NewNumberFromUint(actual_new_len - 1), a)); |
6519 } | 6538 } |
6520 return success; | 6539 return success; |
6521 } | 6540 } |
6522 | 6541 |
6523 | 6542 |
6524 // static | 6543 // static |
6525 bool JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate, | 6544 bool JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate, |
6526 Handle<JSObject> object, | 6545 Handle<JSObject> object, |
6527 Handle<Object> key, | 6546 Handle<Object> key, |
6528 PropertyDescriptor* desc) { | 6547 PropertyDescriptor* desc) { |
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7788 !current->HasNamedInterceptor() && | 7807 !current->HasNamedInterceptor() && |
7789 !current->HasIndexedInterceptor()); | 7808 !current->HasIndexedInterceptor()); |
7790 // Compute the property keys and cache them if possible. | 7809 // Compute the property keys and cache them if possible. |
7791 Handle<FixedArray> enum_keys = | 7810 Handle<FixedArray> enum_keys = |
7792 JSObject::GetEnumPropertyKeys(current, cache_enum_length); | 7811 JSObject::GetEnumPropertyKeys(current, cache_enum_length); |
7793 accumulator.AddKeys(enum_keys); | 7812 accumulator.AddKeys(enum_keys); |
7794 } else { | 7813 } else { |
7795 DCHECK(filter == INCLUDE_SYMBOLS); | 7814 DCHECK(filter == INCLUDE_SYMBOLS); |
7796 PropertyAttributes attr_filter = | 7815 PropertyAttributes attr_filter = |
7797 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); | 7816 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); |
7798 JSObject::CollectOwnElementKeys(current, &accumulator, attr_filter); | 7817 Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( |
| 7818 current->NumberOfOwnProperties(attr_filter)); |
| 7819 current->GetOwnPropertyNames(*property_keys, 0, attr_filter); |
| 7820 accumulator.AddKeys(property_keys); |
7799 } | 7821 } |
7800 | 7822 |
7801 // Add the property keys from the interceptor. | 7823 // Add the property keys from the interceptor. |
7802 if (current->HasNamedInterceptor()) { | 7824 if (current->HasNamedInterceptor()) { |
7803 Handle<JSObject> result; | 7825 Handle<JSObject> result; |
7804 if (JSObject::GetKeysForNamedInterceptor(current, object) | 7826 if (JSObject::GetKeysForNamedInterceptor(current, object) |
7805 .ToHandle(&result)) { | 7827 .ToHandle(&result)) { |
7806 accumulator.AddKeys(result); | 7828 accumulator.AddKeys(result); |
7807 } | 7829 } |
7808 } | 7830 } |
(...skipping 10003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17812 if (cell->value() != *new_value) { | 17834 if (cell->value() != *new_value) { |
17813 cell->set_value(*new_value); | 17835 cell->set_value(*new_value); |
17814 Isolate* isolate = cell->GetIsolate(); | 17836 Isolate* isolate = cell->GetIsolate(); |
17815 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17837 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17816 isolate, DependentCode::kPropertyCellChangedGroup); | 17838 isolate, DependentCode::kPropertyCellChangedGroup); |
17817 } | 17839 } |
17818 } | 17840 } |
17819 | 17841 |
17820 } // namespace internal | 17842 } // namespace internal |
17821 } // namespace v8 | 17843 } // namespace v8 |
OLD | NEW |