| 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 6036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6047 Isolate* isolate = it->isolate(); | 6047 Isolate* isolate = it->isolate(); |
| 6048 // == OrdinaryDefineOwnProperty (O, P, Desc) == | 6048 // == OrdinaryDefineOwnProperty (O, P, Desc) == |
| 6049 // 1. Let current be O.[[GetOwnProperty]](P). | 6049 // 1. Let current be O.[[GetOwnProperty]](P). |
| 6050 // 2. ReturnIfAbrupt(current). | 6050 // 2. ReturnIfAbrupt(current). |
| 6051 PropertyDescriptor current; | 6051 PropertyDescriptor current; |
| 6052 if (!GetOwnPropertyDescriptor(it, ¤t) && | 6052 if (!GetOwnPropertyDescriptor(it, ¤t) && |
| 6053 isolate->has_pending_exception()) { | 6053 isolate->has_pending_exception()) { |
| 6054 return false; | 6054 return false; |
| 6055 } | 6055 } |
| 6056 // 3. Let extensible be the value of the [[Extensible]] internal slot of O. | 6056 // 3. Let extensible be the value of the [[Extensible]] internal slot of O. |
| 6057 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); | 6057 Handle<JSObject> o = Handle<JSObject>::cast(it->GetReceiver()); |
| 6058 bool extensible = JSObject::IsExtensible(object); | 6058 bool extensible = JSObject::IsExtensible(o); |
| 6059 | 6059 |
| 6060 bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc); | 6060 bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc); |
| 6061 bool desc_is_accessor_descriptor = | 6061 bool desc_is_accessor_descriptor = |
| 6062 PropertyDescriptor::IsAccessorDescriptor(desc); | 6062 PropertyDescriptor::IsAccessorDescriptor(desc); |
| 6063 bool desc_is_generic_descriptor = | 6063 bool desc_is_generic_descriptor = |
| 6064 PropertyDescriptor::IsGenericDescriptor(desc); | 6064 PropertyDescriptor::IsGenericDescriptor(desc); |
| 6065 | 6065 |
| 6066 // == ValidateAndApplyPropertyDescriptor (O, P, extensible, Desc, current) == | 6066 // == ValidateAndApplyPropertyDescriptor (O, P, extensible, Desc, current) == |
| 6067 // 2. If current is undefined, then | 6067 // 2. If current is undefined, then |
| 6068 if (current.is_empty()) { | 6068 if (current.is_empty()) { |
| 6069 // 2a. If extensible is false, return false. | 6069 // 2a. If extensible is false, return false. |
| 6070 if (!extensible) { | 6070 if (!extensible) { |
| 6071 if (should_throw == THROW_ON_ERROR) { | 6071 if (should_throw == THROW_ON_ERROR) { |
| 6072 isolate->Throw(*isolate->factory()->NewTypeError( | 6072 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6073 MessageTemplate::kDefineDisallowed, it->GetName())); | 6073 MessageTemplate::kDefineDisallowed, it->GetName())); |
| 6074 } | 6074 } |
| 6075 return false; | 6075 return false; |
| 6076 } | 6076 } |
| 6077 // We have to reset the LookupIterator to handle interceptors properly. | 6077 // We have to use a fresh LookupIterator to handle interceptors properly. |
| 6078 Map* map = Handle<HeapObject>::cast(object)->map(); | 6078 LookupIterator lookup_for_store = |
| 6079 if ((it->IsElement() && map->has_indexed_interceptor()) || | 6079 it->IsElement() ? LookupIterator(isolate, it->GetReceiver(), |
| 6080 (!it->IsElement() && map->has_named_interceptor())) { | 6080 it->index(), LookupIterator::HIDDEN) |
| 6081 it->Restart(); | 6081 : LookupIterator(it->GetReceiver(), it->name(), |
| 6082 } | 6082 LookupIterator::HIDDEN); |
| 6083 | 6083 |
| 6084 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then: | 6084 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then: |
| 6085 // (This is equivalent to !IsAccessorDescriptor(desc).) | 6085 // (This is equivalent to !IsAccessorDescriptor(desc).) |
| 6086 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) == | 6086 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) == |
| 6087 !desc_is_accessor_descriptor); | 6087 !desc_is_accessor_descriptor); |
| 6088 if (!desc_is_accessor_descriptor) { | 6088 if (!desc_is_accessor_descriptor) { |
| 6089 // 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 |
| 6090 // object O whose [[Value]], [[Writable]], [[Enumerable]] and | 6090 // object O whose [[Value]], [[Writable]], [[Enumerable]] and |
| 6091 // [[Configurable]] attribute values are described by Desc. If the value | 6091 // [[Configurable]] attribute values are described by Desc. If the value |
| 6092 // 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 |
| 6093 // created property is set to its default value. | 6093 // created property is set to its default value. |
| 6094 if (!object->IsUndefined()) { | 6094 if (!o->IsUndefined()) { |
| 6095 if (!desc->has_writable()) desc->set_writable(false); | 6095 if (!desc->has_writable()) desc->set_writable(false); |
| 6096 if (!desc->has_enumerable()) desc->set_enumerable(false); | 6096 if (!desc->has_enumerable()) desc->set_enumerable(false); |
| 6097 if (!desc->has_configurable()) desc->set_configurable(false); | 6097 if (!desc->has_configurable()) desc->set_configurable(false); |
| 6098 Handle<Object> value( | 6098 Handle<Object> value( |
| 6099 desc->has_value() | 6099 desc->has_value() |
| 6100 ? desc->value() | 6100 ? desc->value() |
| 6101 : Handle<Object>::cast(isolate->factory()->undefined_value())); | 6101 : Handle<Object>::cast(isolate->factory()->undefined_value())); |
| 6102 MaybeHandle<Object> result = | 6102 MaybeHandle<Object> result = |
| 6103 JSObject::DefineOwnPropertyIgnoreAttributes( | 6103 JSObject::DefineOwnPropertyIgnoreAttributes( |
| 6104 it, value, desc->ToAttributes(), JSObject::DONT_FORCE_FIELD); | 6104 &lookup_for_store, value, desc->ToAttributes(), |
| 6105 JSObject::DONT_FORCE_FIELD); |
| 6105 if (result.is_null()) return false; | 6106 if (result.is_null()) return false; |
| 6106 } | 6107 } |
| 6107 } else { | 6108 } else { |
| 6108 // 2d. Else Desc must be an accessor Property Descriptor, | 6109 // 2d. Else Desc must be an accessor Property Descriptor, |
| 6109 DCHECK(desc_is_accessor_descriptor); | 6110 DCHECK(desc_is_accessor_descriptor); |
| 6110 // 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 |
| 6111 // of object O whose [[Get]], [[Set]], [[Enumerable]] and | 6112 // of object O whose [[Get]], [[Set]], [[Enumerable]] and |
| 6112 // [[Configurable]] attribute values are described by Desc. If the value | 6113 // [[Configurable]] attribute values are described by Desc. If the value |
| 6113 // 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 |
| 6114 // created property is set to its default value. | 6115 // created property is set to its default value. |
| 6115 if (!object->IsUndefined()) { | 6116 if (!o->IsUndefined()) { |
| 6116 if (!desc->has_enumerable()) desc->set_enumerable(false); | 6117 if (!desc->has_enumerable()) desc->set_enumerable(false); |
| 6117 if (!desc->has_configurable()) desc->set_configurable(false); | 6118 if (!desc->has_configurable()) desc->set_configurable(false); |
| 6118 Handle<Object> getter( | 6119 Handle<Object> getter( |
| 6119 desc->has_get() | 6120 desc->has_get() |
| 6120 ? desc->get() | 6121 ? desc->get() |
| 6121 : Handle<Object>::cast(isolate->factory()->undefined_value())); | 6122 : Handle<Object>::cast(isolate->factory()->undefined_value())); |
| 6122 Handle<Object> setter( | 6123 Handle<Object> setter( |
| 6123 desc->has_set() | 6124 desc->has_set() |
| 6124 ? desc->set() | 6125 ? desc->set() |
| 6125 : Handle<Object>::cast(isolate->factory()->undefined_value())); | 6126 : Handle<Object>::cast(isolate->factory()->undefined_value())); |
| 6126 MaybeHandle<Object> result = | 6127 MaybeHandle<Object> result = JSObject::DefineAccessor( |
| 6127 JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes()); | 6128 &lookup_for_store, getter, setter, desc->ToAttributes()); |
| 6128 if (result.is_null()) return false; | 6129 if (result.is_null()) return false; |
| 6129 } | 6130 } |
| 6130 } | 6131 } |
| 6131 // 2e. Return true. | 6132 // 2e. Return true. |
| 6132 return true; | 6133 return true; |
| 6133 } | 6134 } |
| 6134 // 3. Return true, if every field in Desc is absent. | 6135 // 3. Return true, if every field in Desc is absent. |
| 6135 // 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 |
| 6136 // 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 |
| 6137 // in current when compared using the SameValue algorithm. | 6138 // in current when compared using the SameValue algorithm. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6205 } | 6206 } |
| 6206 | 6207 |
| 6207 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both | 6208 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both |
| 6208 // true, then: | 6209 // true, then: |
| 6209 } else if (current_is_data_descriptor && desc_is_data_descriptor) { | 6210 } else if (current_is_data_descriptor && desc_is_data_descriptor) { |
| 6210 // 8a. If the [[Configurable]] field of current is false, then: | 6211 // 8a. If the [[Configurable]] field of current is false, then: |
| 6211 if (!current.configurable()) { | 6212 if (!current.configurable()) { |
| 6212 // [Strong mode] Disallow changing writable -> readonly for | 6213 // [Strong mode] Disallow changing writable -> readonly for |
| 6213 // non-configurable properties. | 6214 // non-configurable properties. |
| 6214 if (current.writable() && desc->has_writable() && !desc->writable() && | 6215 if (current.writable() && desc->has_writable() && !desc->writable() && |
| 6215 object->map()->is_strong()) { | 6216 o->map()->is_strong()) { |
| 6216 if (should_throw == THROW_ON_ERROR) { | 6217 if (should_throw == THROW_ON_ERROR) { |
| 6217 isolate->Throw(*isolate->factory()->NewTypeError( | 6218 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6218 MessageTemplate::kStrongRedefineDisallowed, object, | 6219 MessageTemplate::kStrongRedefineDisallowed, o, it->GetName())); |
| 6219 it->GetName())); | |
| 6220 } | 6220 } |
| 6221 return false; | 6221 return false; |
| 6222 } | 6222 } |
| 6223 // 8a i. Return false, if the [[Writable]] field of current is false and | 6223 // 8a i. Return false, if the [[Writable]] field of current is false and |
| 6224 // the [[Writable]] field of Desc is true. | 6224 // the [[Writable]] field of Desc is true. |
| 6225 if (!current.writable() && desc->has_writable() && desc->writable()) { | 6225 if (!current.writable() && desc->has_writable() && desc->writable()) { |
| 6226 if (should_throw == THROW_ON_ERROR) { | 6226 if (should_throw == THROW_ON_ERROR) { |
| 6227 isolate->Throw(*isolate->factory()->NewTypeError( | 6227 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6228 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6228 MessageTemplate::kRedefineDisallowed, it->GetName())); |
| 6229 } | 6229 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6264 if (should_throw == THROW_ON_ERROR) { | 6264 if (should_throw == THROW_ON_ERROR) { |
| 6265 isolate->Throw(*isolate->factory()->NewTypeError( | 6265 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6266 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6266 MessageTemplate::kRedefineDisallowed, it->GetName())); |
| 6267 } | 6267 } |
| 6268 return false; | 6268 return false; |
| 6269 } | 6269 } |
| 6270 } | 6270 } |
| 6271 } | 6271 } |
| 6272 | 6272 |
| 6273 // 10. If O is not undefined, then: | 6273 // 10. If O is not undefined, then: |
| 6274 if (!object->IsUndefined()) { | 6274 if (!o->IsUndefined()) { |
| 6275 // 10a. For each field of Desc that is present, set the corresponding | 6275 // 10a. For each field of Desc that is present, set the corresponding |
| 6276 // attribute of the property named P of object O to the value of the field. | 6276 // attribute of the property named P of object O to the value of the field. |
| 6277 PropertyAttributes attrs = NONE; | 6277 PropertyAttributes attrs = NONE; |
| 6278 | 6278 |
| 6279 if (desc->has_enumerable()) { | 6279 if (desc->has_enumerable()) { |
| 6280 attrs = static_cast<PropertyAttributes>( | 6280 attrs = static_cast<PropertyAttributes>( |
| 6281 attrs | (desc->enumerable() ? NONE : DONT_ENUM)); | 6281 attrs | (desc->enumerable() ? NONE : DONT_ENUM)); |
| 6282 } else { | 6282 } else { |
| 6283 attrs = static_cast<PropertyAttributes>( | 6283 attrs = static_cast<PropertyAttributes>( |
| 6284 attrs | (current.enumerable() ? NONE : DONT_ENUM)); | 6284 attrs | (current.enumerable() ? NONE : DONT_ENUM)); |
| (...skipping 11547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17832 if (cell->value() != *new_value) { | 17832 if (cell->value() != *new_value) { |
| 17833 cell->set_value(*new_value); | 17833 cell->set_value(*new_value); |
| 17834 Isolate* isolate = cell->GetIsolate(); | 17834 Isolate* isolate = cell->GetIsolate(); |
| 17835 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17835 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17836 isolate, DependentCode::kPropertyCellChangedGroup); | 17836 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17837 } | 17837 } |
| 17838 } | 17838 } |
| 17839 | 17839 |
| 17840 } // namespace internal | 17840 } // namespace internal |
| 17841 } // namespace v8 | 17841 } // namespace v8 |
| OLD | NEW |