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