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 |