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 |