Chromium Code Reviews| 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 6153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6164 | 6164 |
| 6165 return OrdinaryDefineOwnProperty(&it, desc, should_throw); | 6165 return OrdinaryDefineOwnProperty(&it, desc, should_throw); |
| 6166 } | 6166 } |
| 6167 | 6167 |
| 6168 | 6168 |
| 6169 // ES6 9.1.6.1 | 6169 // ES6 9.1.6.1 |
| 6170 // static | 6170 // static |
| 6171 bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, | 6171 bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, |
| 6172 PropertyDescriptor* desc, | 6172 PropertyDescriptor* desc, |
| 6173 ShouldThrow should_throw) { | 6173 ShouldThrow should_throw) { |
| 6174 Isolate* isolate = it->isolate(); | |
| 6175 // == OrdinaryDefineOwnProperty (O, P, Desc) == | |
| 6176 // 1. Let current be O.[[GetOwnProperty]](P). | 6174 // 1. Let current be O.[[GetOwnProperty]](P). |
| 6177 // 2. ReturnIfAbrupt(current). | 6175 // 2. ReturnIfAbrupt(current). |
| 6178 PropertyDescriptor current; | 6176 PropertyDescriptor current; |
| 6179 if (!GetOwnPropertyDescriptor(it, ¤t) && | 6177 if (!GetOwnPropertyDescriptor(it, ¤t) && |
| 6180 isolate->has_pending_exception()) { | 6178 it->isolate()->has_pending_exception()) { |
| 6181 return false; | 6179 return false; |
| 6182 } | 6180 } |
| 6183 // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset | 6181 // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset |
| 6184 // the iterator every time. Currently, the reasons why we need it are: | 6182 // the iterator every time. Currently, the reasons why we need it are: |
| 6185 // - handle interceptors correctly | 6183 // - handle interceptors correctly |
| 6186 // - handle accessors correctly (which might change the holder's map) | 6184 // - handle accessors correctly (which might change the holder's map) |
| 6187 it->Restart(); | 6185 it->Restart(); |
| 6188 // 3. Let extensible be the value of the [[Extensible]] internal slot of O. | 6186 // 3. Let extensible be the value of the [[Extensible]] internal slot of O. |
| 6189 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); | 6187 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); |
| 6190 bool extensible = JSObject::IsExtensible(object); | 6188 bool extensible = JSObject::IsExtensible(object); |
| 6191 | 6189 |
| 6190 return ValidateAndApplyPropertyDescriptor(it, extensible, desc, ¤t, | |
| 6191 should_throw); | |
| 6192 } | |
| 6193 | |
| 6194 | |
| 6195 // ES6 9.1.6.2 | |
| 6196 // static | |
| 6197 bool JSReceiver::IsCompatiblePropertyDescriptor(bool extensible, | |
| 6198 PropertyDescriptor* desc, | |
| 6199 PropertyDescriptor* current, | |
| 6200 Handle<Name> property_name) { | |
| 6201 // 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined, | |
| 6202 // Extensible, Desc, Current). | |
| 6203 return ValidateAndApplyPropertyDescriptor(NULL, extensible, desc, current, | |
| 6204 THROW_ON_ERROR, property_name); | |
| 6205 } | |
| 6206 | |
| 6207 | |
| 6208 // ES6 9.1.6.3 | |
| 6209 // static | |
| 6210 bool JSReceiver::ValidateAndApplyPropertyDescriptor( | |
| 6211 LookupIterator* it, bool extensible, PropertyDescriptor* desc, | |
| 6212 PropertyDescriptor* current, ShouldThrow should_throw, | |
| 6213 Handle<Name> property_name) { | |
| 6214 // We either need a LookupIterator, or a property name. | |
| 6215 DCHECK((it == NULL) != property_name.is_null()); | |
| 6216 Handle<JSObject> object; | |
| 6217 if (it != NULL) object = Handle<JSObject>::cast(it->GetReceiver()); | |
| 6218 Isolate* isolate = it->isolate(); | |
| 6192 bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc); | 6219 bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc); |
| 6193 bool desc_is_accessor_descriptor = | 6220 bool desc_is_accessor_descriptor = |
| 6194 PropertyDescriptor::IsAccessorDescriptor(desc); | 6221 PropertyDescriptor::IsAccessorDescriptor(desc); |
| 6195 bool desc_is_generic_descriptor = | 6222 bool desc_is_generic_descriptor = |
| 6196 PropertyDescriptor::IsGenericDescriptor(desc); | 6223 PropertyDescriptor::IsGenericDescriptor(desc); |
| 6197 | 6224 // 1. (Assert) |
| 6198 // == ValidateAndApplyPropertyDescriptor (O, P, extensible, Desc, current) == | |
| 6199 // 2. If current is undefined, then | 6225 // 2. If current is undefined, then |
| 6200 if (current.is_empty()) { | 6226 if (current->is_empty()) { |
| 6201 // 2a. If extensible is false, return false. | 6227 // 2a. If extensible is false, return false. |
| 6202 if (!extensible) { | 6228 if (!extensible) { |
| 6203 if (should_throw == THROW_ON_ERROR) { | 6229 if (should_throw == THROW_ON_ERROR) { |
| 6204 isolate->Throw(*isolate->factory()->NewTypeError( | 6230 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6205 MessageTemplate::kDefineDisallowed, it->GetName())); | 6231 MessageTemplate::kDefineDisallowed, |
| 6232 it != NULL ? it->GetName() : property_name)); | |
|
Camillo Bruni
2015/11/13 16:35:43
myabe directly assign the propert_name from the lo
Jakob Kummerow
2015/11/13 16:37:49
As discussed, GetName() is intentionally only call
| |
| 6206 } | 6233 } |
| 6207 return false; | 6234 return false; |
| 6208 } | 6235 } |
| 6209 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then: | 6236 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then: |
| 6210 // (This is equivalent to !IsAccessorDescriptor(desc).) | 6237 // (This is equivalent to !IsAccessorDescriptor(desc).) |
| 6211 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) == | 6238 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) == |
| 6212 !desc_is_accessor_descriptor); | 6239 !desc_is_accessor_descriptor); |
| 6213 if (!desc_is_accessor_descriptor) { | 6240 if (!desc_is_accessor_descriptor) { |
| 6214 // 2c i. If O is not undefined, create an own data property named P of | 6241 // 2c i. If O is not undefined, create an own data property named P of |
| 6215 // object O whose [[Value]], [[Writable]], [[Enumerable]] and | 6242 // object O whose [[Value]], [[Writable]], [[Enumerable]] and |
| 6216 // [[Configurable]] attribute values are described by Desc. If the value | 6243 // [[Configurable]] attribute values are described by Desc. If the value |
| 6217 // of an attribute field of Desc is absent, the attribute of the newly | 6244 // of an attribute field of Desc is absent, the attribute of the newly |
| 6218 // created property is set to its default value. | 6245 // created property is set to its default value. |
| 6219 if (!object->IsUndefined()) { | 6246 if (it != NULL) { |
| 6220 if (!desc->has_writable()) desc->set_writable(false); | 6247 if (!desc->has_writable()) desc->set_writable(false); |
| 6221 if (!desc->has_enumerable()) desc->set_enumerable(false); | 6248 if (!desc->has_enumerable()) desc->set_enumerable(false); |
| 6222 if (!desc->has_configurable()) desc->set_configurable(false); | 6249 if (!desc->has_configurable()) desc->set_configurable(false); |
| 6223 Handle<Object> value( | 6250 Handle<Object> value( |
| 6224 desc->has_value() | 6251 desc->has_value() |
| 6225 ? desc->value() | 6252 ? desc->value() |
| 6226 : Handle<Object>::cast(isolate->factory()->undefined_value())); | 6253 : Handle<Object>::cast(isolate->factory()->undefined_value())); |
| 6227 MaybeHandle<Object> result = | 6254 MaybeHandle<Object> result = |
| 6228 JSObject::DefineOwnPropertyIgnoreAttributes( | 6255 JSObject::DefineOwnPropertyIgnoreAttributes( |
| 6229 it, value, desc->ToAttributes(), JSObject::DONT_FORCE_FIELD); | 6256 it, value, desc->ToAttributes(), JSObject::DONT_FORCE_FIELD); |
| 6230 if (result.is_null()) return false; | 6257 if (result.is_null()) return false; |
| 6231 } | 6258 } |
| 6232 } else { | 6259 } else { |
| 6233 // 2d. Else Desc must be an accessor Property Descriptor, | 6260 // 2d. Else Desc must be an accessor Property Descriptor, |
| 6234 DCHECK(desc_is_accessor_descriptor); | 6261 DCHECK(desc_is_accessor_descriptor); |
| 6235 // 2d i. If O is not undefined, create an own accessor property named P | 6262 // 2d i. If O is not undefined, create an own accessor property named P |
| 6236 // of object O whose [[Get]], [[Set]], [[Enumerable]] and | 6263 // of object O whose [[Get]], [[Set]], [[Enumerable]] and |
| 6237 // [[Configurable]] attribute values are described by Desc. If the value | 6264 // [[Configurable]] attribute values are described by Desc. If the value |
| 6238 // of an attribute field of Desc is absent, the attribute of the newly | 6265 // of an attribute field of Desc is absent, the attribute of the newly |
| 6239 // created property is set to its default value. | 6266 // created property is set to its default value. |
| 6240 if (!object->IsUndefined()) { | 6267 if (it != NULL) { |
| 6241 if (!desc->has_enumerable()) desc->set_enumerable(false); | 6268 if (!desc->has_enumerable()) desc->set_enumerable(false); |
| 6242 if (!desc->has_configurable()) desc->set_configurable(false); | 6269 if (!desc->has_configurable()) desc->set_configurable(false); |
| 6243 Handle<Object> getter( | 6270 Handle<Object> getter( |
| 6244 desc->has_get() | 6271 desc->has_get() |
| 6245 ? desc->get() | 6272 ? desc->get() |
| 6246 : Handle<Object>::cast(isolate->factory()->null_value())); | 6273 : Handle<Object>::cast(isolate->factory()->null_value())); |
| 6247 Handle<Object> setter( | 6274 Handle<Object> setter( |
| 6248 desc->has_set() | 6275 desc->has_set() |
| 6249 ? desc->set() | 6276 ? desc->set() |
| 6250 : Handle<Object>::cast(isolate->factory()->null_value())); | 6277 : Handle<Object>::cast(isolate->factory()->null_value())); |
| 6251 MaybeHandle<Object> result = | 6278 MaybeHandle<Object> result = |
| 6252 JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes()); | 6279 JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes()); |
| 6253 if (result.is_null()) return false; | 6280 if (result.is_null()) return false; |
| 6254 } | 6281 } |
| 6255 } | 6282 } |
| 6256 // 2e. Return true. | 6283 // 2e. Return true. |
| 6257 return true; | 6284 return true; |
| 6258 } | 6285 } |
| 6259 // 3. Return true, if every field in Desc is absent. | 6286 // 3. Return true, if every field in Desc is absent. |
| 6260 // 4. Return true, if every field in Desc also occurs in current and the | 6287 // 4. Return true, if every field in Desc also occurs in current and the |
| 6261 // value of every field in Desc is the same value as the corresponding field | 6288 // value of every field in Desc is the same value as the corresponding field |
| 6262 // in current when compared using the SameValue algorithm. | 6289 // in current when compared using the SameValue algorithm. |
| 6263 if ((!desc->has_enumerable() || desc->enumerable() == current.enumerable()) && | 6290 if ((!desc->has_enumerable() || |
| 6291 desc->enumerable() == current->enumerable()) && | |
| 6264 (!desc->has_configurable() || | 6292 (!desc->has_configurable() || |
| 6265 desc->configurable() == current.configurable()) && | 6293 desc->configurable() == current->configurable()) && |
| 6266 (!desc->has_value() || | 6294 (!desc->has_value() || |
| 6267 (current.has_value() && current.value()->SameValue(*desc->value()))) && | 6295 (current->has_value() && current->value()->SameValue(*desc->value()))) && |
| 6268 (!desc->has_writable() || | 6296 (!desc->has_writable() || |
| 6269 (current.has_writable() && current.writable() == desc->writable())) && | 6297 (current->has_writable() && current->writable() == desc->writable())) && |
| 6270 (!desc->has_get() || | 6298 (!desc->has_get() || |
| 6271 (current.has_get() && current.get()->SameValue(*desc->get()))) && | 6299 (current->has_get() && current->get()->SameValue(*desc->get()))) && |
| 6272 (!desc->has_set() || | 6300 (!desc->has_set() || |
| 6273 (current.has_set() && current.set()->SameValue(*desc->set())))) { | 6301 (current->has_set() && current->set()->SameValue(*desc->set())))) { |
| 6274 return true; | 6302 return true; |
| 6275 } | 6303 } |
| 6276 // 5. If the [[Configurable]] field of current is false, then | 6304 // 5. If the [[Configurable]] field of current is false, then |
| 6277 if (!current.configurable()) { | 6305 if (!current->configurable()) { |
| 6278 // 5a. Return false, if the [[Configurable]] field of Desc is true. | 6306 // 5a. Return false, if the [[Configurable]] field of Desc is true. |
| 6279 if (desc->has_configurable() && desc->configurable()) { | 6307 if (desc->has_configurable() && desc->configurable()) { |
| 6280 if (should_throw == THROW_ON_ERROR) { | 6308 if (should_throw == THROW_ON_ERROR) { |
| 6281 isolate->Throw(*isolate->factory()->NewTypeError( | 6309 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6282 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6310 MessageTemplate::kRedefineDisallowed, |
| 6311 it != NULL ? it->GetName() : property_name)); | |
| 6283 } | 6312 } |
| 6284 return false; | 6313 return false; |
| 6285 } | 6314 } |
| 6286 // 5b. Return false, if the [[Enumerable]] field of Desc is present and the | 6315 // 5b. Return false, if the [[Enumerable]] field of Desc is present and the |
| 6287 // [[Enumerable]] fields of current and Desc are the Boolean negation of | 6316 // [[Enumerable]] fields of current and Desc are the Boolean negation of |
| 6288 // each other. | 6317 // each other. |
| 6289 if (desc->has_enumerable() && desc->enumerable() != current.enumerable()) { | 6318 if (desc->has_enumerable() && desc->enumerable() != current->enumerable()) { |
| 6290 if (should_throw == THROW_ON_ERROR) { | 6319 if (should_throw == THROW_ON_ERROR) { |
| 6291 isolate->Throw(*isolate->factory()->NewTypeError( | 6320 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6292 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6321 MessageTemplate::kRedefineDisallowed, |
| 6322 it != NULL ? it->GetName() : property_name)); | |
| 6293 } | 6323 } |
| 6294 return false; | 6324 return false; |
| 6295 } | 6325 } |
| 6296 } | 6326 } |
| 6297 | 6327 |
| 6298 bool current_is_data_descriptor = | 6328 bool current_is_data_descriptor = |
| 6299 PropertyDescriptor::IsDataDescriptor(¤t); | 6329 PropertyDescriptor::IsDataDescriptor(current); |
| 6300 // 6. If IsGenericDescriptor(Desc) is true, no further validation is required. | 6330 // 6. If IsGenericDescriptor(Desc) is true, no further validation is required. |
| 6301 if (desc_is_generic_descriptor) { | 6331 if (desc_is_generic_descriptor) { |
| 6302 // Nothing to see here. | 6332 // Nothing to see here. |
| 6303 | 6333 |
| 6304 // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have | 6334 // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have |
| 6305 // different results, then: | 6335 // different results, then: |
| 6306 } else if (current_is_data_descriptor != desc_is_data_descriptor) { | 6336 } else if (current_is_data_descriptor != desc_is_data_descriptor) { |
| 6307 // 7a. Return false, if the [[Configurable]] field of current is false. | 6337 // 7a. Return false, if the [[Configurable]] field of current is false. |
| 6308 if (!current.configurable()) { | 6338 if (!current->configurable()) { |
| 6309 if (should_throw == THROW_ON_ERROR) { | 6339 if (should_throw == THROW_ON_ERROR) { |
| 6310 isolate->Throw(*isolate->factory()->NewTypeError( | 6340 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6311 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6341 MessageTemplate::kRedefineDisallowed, |
| 6342 it != NULL ? it->GetName() : property_name)); | |
| 6312 } | 6343 } |
| 6313 return false; | 6344 return false; |
| 6314 } | 6345 } |
| 6315 // 7b. If IsDataDescriptor(current) is true, then: | 6346 // 7b. If IsDataDescriptor(current) is true, then: |
| 6316 if (current_is_data_descriptor) { | 6347 if (current_is_data_descriptor) { |
| 6317 // 7b i. If O is not undefined, convert the property named P of object O | 6348 // 7b i. If O is not undefined, convert the property named P of object O |
| 6318 // from a data property to an accessor property. Preserve the existing | 6349 // from a data property to an accessor property. Preserve the existing |
| 6319 // values of the converted property's [[Configurable]] and [[Enumerable]] | 6350 // values of the converted property's [[Configurable]] and [[Enumerable]] |
| 6320 // attributes and set the rest of the property's attributes to their | 6351 // attributes and set the rest of the property's attributes to their |
| 6321 // default values. | 6352 // default values. |
| 6322 // --> Folded into step 10. | 6353 // --> Folded into step 10. |
| 6323 } else { | 6354 } else { |
| 6324 // 7c i. If O is not undefined, convert the property named P of object O | 6355 // 7c i. If O is not undefined, convert the property named P of object O |
| 6325 // from an accessor property to a data property. Preserve the existing | 6356 // from an accessor property to a data property. Preserve the existing |
| 6326 // values of the converted property’s [[Configurable]] and [[Enumerable]] | 6357 // values of the converted property’s [[Configurable]] and [[Enumerable]] |
| 6327 // attributes and set the rest of the property’s attributes to their | 6358 // attributes and set the rest of the property’s attributes to their |
| 6328 // default values. | 6359 // default values. |
| 6329 // --> Folded into step 10. | 6360 // --> Folded into step 10. |
| 6330 } | 6361 } |
| 6331 | 6362 |
| 6332 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both | 6363 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both |
| 6333 // true, then: | 6364 // true, then: |
| 6334 } else if (current_is_data_descriptor && desc_is_data_descriptor) { | 6365 } else if (current_is_data_descriptor && desc_is_data_descriptor) { |
| 6335 // 8a. If the [[Configurable]] field of current is false, then: | 6366 // 8a. If the [[Configurable]] field of current is false, then: |
| 6336 if (!current.configurable()) { | 6367 if (!current->configurable()) { |
| 6337 // [Strong mode] Disallow changing writable -> readonly for | 6368 // [Strong mode] Disallow changing writable -> readonly for |
| 6338 // non-configurable properties. | 6369 // non-configurable properties. |
| 6339 if (current.writable() && desc->has_writable() && !desc->writable() && | 6370 if (it != NULL && current->writable() && desc->has_writable() && |
| 6340 object->map()->is_strong()) { | 6371 !desc->writable() && object->map()->is_strong()) { |
| 6341 if (should_throw == THROW_ON_ERROR) { | 6372 if (should_throw == THROW_ON_ERROR) { |
| 6342 isolate->Throw(*isolate->factory()->NewTypeError( | 6373 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6343 MessageTemplate::kStrongRedefineDisallowed, object, | 6374 MessageTemplate::kStrongRedefineDisallowed, object, |
| 6344 it->GetName())); | 6375 it->GetName())); |
| 6345 } | 6376 } |
| 6346 return false; | 6377 return false; |
| 6347 } | 6378 } |
| 6348 // 8a i. Return false, if the [[Writable]] field of current is false and | 6379 // 8a i. Return false, if the [[Writable]] field of current is false and |
| 6349 // the [[Writable]] field of Desc is true. | 6380 // the [[Writable]] field of Desc is true. |
| 6350 if (!current.writable() && desc->has_writable() && desc->writable()) { | 6381 if (!current->writable() && desc->has_writable() && desc->writable()) { |
| 6351 if (should_throw == THROW_ON_ERROR) { | 6382 if (should_throw == THROW_ON_ERROR) { |
| 6352 isolate->Throw(*isolate->factory()->NewTypeError( | 6383 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6353 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6384 MessageTemplate::kRedefineDisallowed, |
| 6385 it != NULL ? it->GetName() : property_name)); | |
| 6354 } | 6386 } |
| 6355 return false; | 6387 return false; |
| 6356 } | 6388 } |
| 6357 // 8a ii. If the [[Writable]] field of current is false, then: | 6389 // 8a ii. If the [[Writable]] field of current is false, then: |
| 6358 if (!current.writable()) { | 6390 if (!current->writable()) { |
| 6359 // 8a ii 1. Return false, if the [[Value]] field of Desc is present and | 6391 // 8a ii 1. Return false, if the [[Value]] field of Desc is present and |
| 6360 // SameValue(Desc.[[Value]], current.[[Value]]) is false. | 6392 // SameValue(Desc.[[Value]], current.[[Value]]) is false. |
| 6361 if (desc->has_value() && !desc->value()->SameValue(*current.value())) { | 6393 if (desc->has_value() && !desc->value()->SameValue(*current->value())) { |
| 6362 if (should_throw == THROW_ON_ERROR) { | 6394 if (should_throw == THROW_ON_ERROR) { |
| 6363 isolate->Throw(*isolate->factory()->NewTypeError( | 6395 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6364 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6396 MessageTemplate::kRedefineDisallowed, |
| 6397 it != NULL ? it->GetName() : property_name)); | |
| 6365 } | 6398 } |
| 6366 return false; | 6399 return false; |
| 6367 } | 6400 } |
| 6368 } | 6401 } |
| 6369 } | 6402 } |
| 6370 } else { | 6403 } else { |
| 6371 // 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc) | 6404 // 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc) |
| 6372 // are both true, | 6405 // are both true, |
| 6373 DCHECK(PropertyDescriptor::IsAccessorDescriptor(¤t) && | 6406 DCHECK(PropertyDescriptor::IsAccessorDescriptor(current) && |
| 6374 desc_is_accessor_descriptor); | 6407 desc_is_accessor_descriptor); |
| 6375 // 9a. If the [[Configurable]] field of current is false, then: | 6408 // 9a. If the [[Configurable]] field of current is false, then: |
| 6376 if (!current.configurable()) { | 6409 if (!current->configurable()) { |
| 6377 // 9a i. Return false, if the [[Set]] field of Desc is present and | 6410 // 9a i. Return false, if the [[Set]] field of Desc is present and |
| 6378 // SameValue(Desc.[[Set]], current.[[Set]]) is false. | 6411 // SameValue(Desc.[[Set]], current.[[Set]]) is false. |
| 6379 if (desc->has_set() && !desc->set()->SameValue(*current.set())) { | 6412 if (desc->has_set() && !desc->set()->SameValue(*current->set())) { |
| 6380 if (should_throw == THROW_ON_ERROR) { | 6413 if (should_throw == THROW_ON_ERROR) { |
| 6381 isolate->Throw(*isolate->factory()->NewTypeError( | 6414 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6382 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6415 MessageTemplate::kRedefineDisallowed, |
| 6416 it != NULL ? it->GetName() : property_name)); | |
| 6383 } | 6417 } |
| 6384 return false; | 6418 return false; |
| 6385 } | 6419 } |
| 6386 // 9a ii. Return false, if the [[Get]] field of Desc is present and | 6420 // 9a ii. Return false, if the [[Get]] field of Desc is present and |
| 6387 // SameValue(Desc.[[Get]], current.[[Get]]) is false. | 6421 // SameValue(Desc.[[Get]], current.[[Get]]) is false. |
| 6388 if (desc->has_get() && !desc->get()->SameValue(*current.get())) { | 6422 if (desc->has_get() && !desc->get()->SameValue(*current->get())) { |
| 6389 if (should_throw == THROW_ON_ERROR) { | 6423 if (should_throw == THROW_ON_ERROR) { |
| 6390 isolate->Throw(*isolate->factory()->NewTypeError( | 6424 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6391 MessageTemplate::kRedefineDisallowed, it->GetName())); | 6425 MessageTemplate::kRedefineDisallowed, |
| 6426 it != NULL ? it->GetName() : property_name)); | |
| 6392 } | 6427 } |
| 6393 return false; | 6428 return false; |
| 6394 } | 6429 } |
| 6395 } | 6430 } |
| 6396 } | 6431 } |
| 6397 | 6432 |
| 6398 // 10. If O is not undefined, then: | 6433 // 10. If O is not undefined, then: |
| 6399 if (!object->IsUndefined()) { | 6434 if (it != NULL) { |
| 6400 // 10a. For each field of Desc that is present, set the corresponding | 6435 // 10a. For each field of Desc that is present, set the corresponding |
| 6401 // attribute of the property named P of object O to the value of the field. | 6436 // attribute of the property named P of object O to the value of the field. |
| 6402 PropertyAttributes attrs = NONE; | 6437 PropertyAttributes attrs = NONE; |
| 6403 | 6438 |
| 6404 if (desc->has_enumerable()) { | 6439 if (desc->has_enumerable()) { |
| 6405 attrs = static_cast<PropertyAttributes>( | 6440 attrs = static_cast<PropertyAttributes>( |
| 6406 attrs | (desc->enumerable() ? NONE : DONT_ENUM)); | 6441 attrs | (desc->enumerable() ? NONE : DONT_ENUM)); |
| 6407 } else { | 6442 } else { |
| 6408 attrs = static_cast<PropertyAttributes>( | 6443 attrs = static_cast<PropertyAttributes>( |
| 6409 attrs | (current.enumerable() ? NONE : DONT_ENUM)); | 6444 attrs | (current->enumerable() ? NONE : DONT_ENUM)); |
| 6410 } | 6445 } |
| 6411 if (desc->has_configurable()) { | 6446 if (desc->has_configurable()) { |
| 6412 attrs = static_cast<PropertyAttributes>( | 6447 attrs = static_cast<PropertyAttributes>( |
| 6413 attrs | (desc->configurable() ? NONE : DONT_DELETE)); | 6448 attrs | (desc->configurable() ? NONE : DONT_DELETE)); |
| 6414 } else { | 6449 } else { |
| 6415 attrs = static_cast<PropertyAttributes>( | 6450 attrs = static_cast<PropertyAttributes>( |
| 6416 attrs | (current.configurable() ? NONE : DONT_DELETE)); | 6451 attrs | (current->configurable() ? NONE : DONT_DELETE)); |
| 6417 } | 6452 } |
| 6418 if (desc_is_data_descriptor || | 6453 if (desc_is_data_descriptor || |
| 6419 (desc_is_generic_descriptor && current_is_data_descriptor)) { | 6454 (desc_is_generic_descriptor && current_is_data_descriptor)) { |
| 6420 if (desc->has_writable()) { | 6455 if (desc->has_writable()) { |
| 6421 attrs = static_cast<PropertyAttributes>( | 6456 attrs = static_cast<PropertyAttributes>( |
| 6422 attrs | (desc->writable() ? NONE : READ_ONLY)); | 6457 attrs | (desc->writable() ? NONE : READ_ONLY)); |
| 6423 } else { | 6458 } else { |
| 6424 attrs = static_cast<PropertyAttributes>( | 6459 attrs = static_cast<PropertyAttributes>( |
| 6425 attrs | (current.writable() ? NONE : READ_ONLY)); | 6460 attrs | (current->writable() ? NONE : READ_ONLY)); |
| 6426 } | 6461 } |
| 6427 Handle<Object> value( | 6462 Handle<Object> value( |
| 6428 desc->has_value() ? desc->value() | 6463 desc->has_value() ? desc->value() |
| 6429 : current.has_value() | 6464 : current->has_value() |
| 6430 ? current.value() | 6465 ? current->value() |
| 6431 : Handle<Object>::cast( | 6466 : Handle<Object>::cast( |
| 6432 isolate->factory()->undefined_value())); | 6467 isolate->factory()->undefined_value())); |
| 6433 MaybeHandle<Object> result = JSObject::DefineOwnPropertyIgnoreAttributes( | 6468 MaybeHandle<Object> result = JSObject::DefineOwnPropertyIgnoreAttributes( |
| 6434 it, value, attrs, JSObject::DONT_FORCE_FIELD); | 6469 it, value, attrs, JSObject::DONT_FORCE_FIELD); |
| 6435 if (result.is_null()) return false; | 6470 if (result.is_null()) return false; |
| 6436 } else { | 6471 } else { |
| 6437 DCHECK(desc_is_accessor_descriptor || | 6472 DCHECK(desc_is_accessor_descriptor || |
| 6438 (desc_is_generic_descriptor && | 6473 (desc_is_generic_descriptor && |
| 6439 PropertyDescriptor::IsAccessorDescriptor(¤t))); | 6474 PropertyDescriptor::IsAccessorDescriptor(current))); |
| 6440 Handle<Object> getter( | 6475 Handle<Object> getter( |
| 6441 desc->has_get() | 6476 desc->has_get() |
| 6442 ? desc->get() | 6477 ? desc->get() |
| 6443 : current.has_get() | 6478 : current->has_get() |
| 6444 ? current.get() | 6479 ? current->get() |
| 6445 : Handle<Object>::cast(isolate->factory()->null_value())); | 6480 : Handle<Object>::cast(isolate->factory()->null_value())); |
| 6446 Handle<Object> setter( | 6481 Handle<Object> setter( |
| 6447 desc->has_set() | 6482 desc->has_set() |
| 6448 ? desc->set() | 6483 ? desc->set() |
| 6449 : current.has_set() | 6484 : current->has_set() |
| 6450 ? current.set() | 6485 ? current->set() |
| 6451 : Handle<Object>::cast(isolate->factory()->null_value())); | 6486 : Handle<Object>::cast(isolate->factory()->null_value())); |
| 6452 MaybeHandle<Object> result = | 6487 MaybeHandle<Object> result = |
| 6453 JSObject::DefineAccessor(it, getter, setter, attrs); | 6488 JSObject::DefineAccessor(it, getter, setter, attrs); |
| 6454 if (result.is_null()) return false; | 6489 if (result.is_null()) return false; |
| 6455 } | 6490 } |
| 6456 } | 6491 } |
| 6457 | 6492 |
| 6458 // 11. Return true. | 6493 // 11. Return true. |
| 6459 return true; | 6494 return true; |
| 6460 } | 6495 } |
| (...skipping 11495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 17956 if (cell->value() != *new_value) { | 17991 if (cell->value() != *new_value) { |
| 17957 cell->set_value(*new_value); | 17992 cell->set_value(*new_value); |
| 17958 Isolate* isolate = cell->GetIsolate(); | 17993 Isolate* isolate = cell->GetIsolate(); |
| 17959 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17994 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17960 isolate, DependentCode::kPropertyCellChangedGroup); | 17995 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17961 } | 17996 } |
| 17962 } | 17997 } |
| 17963 | 17998 |
| 17964 } // namespace internal | 17999 } // namespace internal |
| 17965 } // namespace v8 | 18000 } // namespace v8 |
| OLD | NEW |