| 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 <sstream> | 5 #include <sstream> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 PropertyCell::cast(property_dictionary->ValueAt(entry))); | 523 PropertyCell::cast(property_dictionary->ValueAt(entry))); |
| 524 PropertyCell::SetValueInferType(cell, value); | 524 PropertyCell::SetValueInferType(cell, value); |
| 525 // Please note we have to update the property details. | 525 // Please note we have to update the property details. |
| 526 property_dictionary->DetailsAtPut(entry, details); | 526 property_dictionary->DetailsAtPut(entry, details); |
| 527 } else { | 527 } else { |
| 528 property_dictionary->SetEntry(entry, name, value, details); | 528 property_dictionary->SetEntry(entry, name, value, details); |
| 529 } | 529 } |
| 530 } | 530 } |
| 531 | 531 |
| 532 | 532 |
| 533 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | |
| 534 Handle<Name> name, | |
| 535 DeleteMode mode) { | |
| 536 DCHECK(!object->HasFastProperties()); | |
| 537 Isolate* isolate = object->GetIsolate(); | |
| 538 Handle<NameDictionary> dictionary(object->property_dictionary()); | |
| 539 int entry = dictionary->FindEntry(name); | |
| 540 if (entry != NameDictionary::kNotFound) { | |
| 541 // If we have a global object set the cell to the hole. | |
| 542 if (object->IsGlobalObject()) { | |
| 543 PropertyDetails details = dictionary->DetailsAt(entry); | |
| 544 if (!details.IsConfigurable()) { | |
| 545 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | |
| 546 // When forced to delete global properties, we have to make a | |
| 547 // map change to invalidate any ICs that think they can load | |
| 548 // from the non-configurable cell without checking if it contains | |
| 549 // the hole value. | |
| 550 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | |
| 551 DCHECK(new_map->is_dictionary_map()); | |
| 552 #if TRACE_MAPS | |
| 553 if (FLAG_trace_maps) { | |
| 554 PrintF("[TraceMaps: GlobalDeleteNormalized from= %p to= %p ]\n", | |
| 555 reinterpret_cast<void*>(object->map()), | |
| 556 reinterpret_cast<void*>(*new_map)); | |
| 557 } | |
| 558 #endif | |
| 559 JSObject::MigrateToMap(object, new_map); | |
| 560 // Optimized code does not check for the hole value for non-configurable | |
| 561 // properties. | |
| 562 Deoptimizer::DeoptimizeGlobalObject(*object); | |
| 563 } | |
| 564 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | |
| 565 Handle<Object> value = isolate->factory()->the_hole_value(); | |
| 566 PropertyCell::SetValueInferType(cell, value); | |
| 567 dictionary->DetailsAtPut(entry, details.AsDeleted()); | |
| 568 } else { | |
| 569 Handle<Object> deleted( | |
| 570 NameDictionary::DeleteProperty(dictionary, entry, mode)); | |
| 571 if (*deleted == isolate->heap()->true_value()) { | |
| 572 Handle<NameDictionary> new_properties = | |
| 573 NameDictionary::Shrink(dictionary, name); | |
| 574 object->set_properties(*new_properties); | |
| 575 } | |
| 576 return deleted; | |
| 577 } | |
| 578 } | |
| 579 return isolate->factory()->true_value(); | |
| 580 } | |
| 581 | |
| 582 | |
| 583 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, | 533 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, |
| 584 Handle<Object> object, | 534 Handle<Object> object, |
| 585 Handle<Object> receiver, | 535 Handle<Object> receiver, |
| 586 uint32_t index) { | 536 uint32_t index) { |
| 587 if (object->IsUndefined()) { | 537 if (object->IsUndefined()) { |
| 588 // TODO(verwaest): Why is this check here? | 538 // TODO(verwaest): Why is this check here? |
| 589 UNREACHABLE(); | 539 UNREACHABLE(); |
| 590 return isolate->factory()->undefined_value(); | 540 return isolate->factory()->undefined_value(); |
| 591 } | 541 } |
| 592 | 542 |
| (...skipping 2943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3536 } | 3486 } |
| 3537 | 3487 |
| 3538 if (strict_mode == SLOPPY) return value; | 3488 if (strict_mode == SLOPPY) return value; |
| 3539 Handle<Object> args2[] = { name, proxy }; | 3489 Handle<Object> args2[] = { name, proxy }; |
| 3540 THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback", | 3490 THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback", |
| 3541 HandleVector(args2, arraysize(args2))), | 3491 HandleVector(args2, arraysize(args2))), |
| 3542 Object); | 3492 Object); |
| 3543 } | 3493 } |
| 3544 | 3494 |
| 3545 | 3495 |
| 3546 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( | 3496 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(Handle<JSProxy> proxy, |
| 3547 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { | 3497 Handle<Name> name, |
| 3498 StrictMode strict_mode) { |
| 3548 Isolate* isolate = proxy->GetIsolate(); | 3499 Isolate* isolate = proxy->GetIsolate(); |
| 3549 | 3500 |
| 3550 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3501 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3551 if (name->IsSymbol()) return isolate->factory()->false_value(); | 3502 if (name->IsSymbol()) return isolate->factory()->false_value(); |
| 3552 | 3503 |
| 3553 Handle<Object> args[] = { name }; | 3504 Handle<Object> args[] = { name }; |
| 3554 Handle<Object> result; | 3505 Handle<Object> result; |
| 3555 ASSIGN_RETURN_ON_EXCEPTION( | 3506 ASSIGN_RETURN_ON_EXCEPTION( |
| 3556 isolate, result, | 3507 isolate, result, |
| 3557 CallTrap(proxy, | 3508 CallTrap(proxy, |
| 3558 "delete", | 3509 "delete", |
| 3559 Handle<Object>(), | 3510 Handle<Object>(), |
| 3560 arraysize(args), | 3511 arraysize(args), |
| 3561 args), | 3512 args), |
| 3562 Object); | 3513 Object); |
| 3563 | 3514 |
| 3564 bool result_bool = result->BooleanValue(); | 3515 bool result_bool = result->BooleanValue(); |
| 3565 if (mode == STRICT_DELETION && !result_bool) { | 3516 if (strict_mode == STRICT && !result_bool) { |
| 3566 Handle<Object> handler(proxy->handler(), isolate); | 3517 Handle<Object> handler(proxy->handler(), isolate); |
| 3567 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( | 3518 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( |
| 3568 STATIC_CHAR_VECTOR("delete")); | 3519 STATIC_CHAR_VECTOR("delete")); |
| 3569 Handle<Object> args[] = { handler, trap_name }; | 3520 Handle<Object> args[] = { handler, trap_name }; |
| 3570 THROW_NEW_ERROR(isolate, NewTypeError("handler_failed", | 3521 THROW_NEW_ERROR(isolate, NewTypeError("handler_failed", |
| 3571 HandleVector(args, arraysize(args))), | 3522 HandleVector(args, arraysize(args))), |
| 3572 Object); | 3523 Object); |
| 3573 } | 3524 } |
| 3574 return isolate->factory()->ToBoolean(result_bool); | 3525 return isolate->factory()->ToBoolean(result_bool); |
| 3575 } | 3526 } |
| 3576 | 3527 |
| 3577 | 3528 |
| 3578 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( | 3529 MaybeHandle<Object> JSProxy::DeleteElementWithHandler(Handle<JSProxy> proxy, |
| 3579 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { | 3530 uint32_t index, |
| 3531 StrictMode strict_mode) { |
| 3580 Isolate* isolate = proxy->GetIsolate(); | 3532 Isolate* isolate = proxy->GetIsolate(); |
| 3581 Handle<String> name = isolate->factory()->Uint32ToString(index); | 3533 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 3582 return JSProxy::DeletePropertyWithHandler(proxy, name, mode); | 3534 return JSProxy::DeletePropertyWithHandler(proxy, name, strict_mode); |
| 3583 } | 3535 } |
| 3584 | 3536 |
| 3585 | 3537 |
| 3586 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler( | 3538 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler( |
| 3587 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) { | 3539 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) { |
| 3588 Isolate* isolate = proxy->GetIsolate(); | 3540 Isolate* isolate = proxy->GetIsolate(); |
| 3589 HandleScope scope(isolate); | 3541 HandleScope scope(isolate); |
| 3590 | 3542 |
| 3591 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3543 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3592 if (name->IsSymbol()) return maybe(ABSENT); | 3544 if (name->IsSymbol()) return maybe(ABSENT); |
| (...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4850 isolate, interceptor->data(), *object, *object); | 4802 isolate, interceptor->data(), *object, *object); |
| 4851 v8::Handle<v8::Boolean> result = args.Call(deleter, index); | 4803 v8::Handle<v8::Boolean> result = args.Call(deleter, index); |
| 4852 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 4804 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 4853 if (!result.IsEmpty()) { | 4805 if (!result.IsEmpty()) { |
| 4854 DCHECK(result->IsBoolean()); | 4806 DCHECK(result->IsBoolean()); |
| 4855 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 4807 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
| 4856 result_internal->VerifyApiCallResultType(); | 4808 result_internal->VerifyApiCallResultType(); |
| 4857 // Rebox CustomArguments::kReturnValueOffset before returning. | 4809 // Rebox CustomArguments::kReturnValueOffset before returning. |
| 4858 return handle(*result_internal, isolate); | 4810 return handle(*result_internal, isolate); |
| 4859 } | 4811 } |
| 4860 MaybeHandle<Object> delete_result = object->GetElementsAccessor()->Delete( | 4812 // TODO(verwaest): Shouldn't this be the mode that was passed in? |
| 4861 object, index, NORMAL_DELETION); | 4813 MaybeHandle<Object> delete_result = |
| 4814 object->GetElementsAccessor()->Delete(object, index, SLOPPY); |
| 4862 return delete_result; | 4815 return delete_result; |
| 4863 } | 4816 } |
| 4864 | 4817 |
| 4865 | 4818 |
| 4866 MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, | 4819 MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, |
| 4867 uint32_t index, | 4820 uint32_t index, |
| 4868 DeleteMode mode) { | 4821 StrictMode strict_mode) { |
| 4869 Isolate* isolate = object->GetIsolate(); | 4822 Isolate* isolate = object->GetIsolate(); |
| 4870 Factory* factory = isolate->factory(); | 4823 Factory* factory = isolate->factory(); |
| 4871 | 4824 |
| 4872 // Check access rights if needed. | 4825 // Check access rights if needed. |
| 4873 if (object->IsAccessCheckNeeded() && | 4826 if (object->IsAccessCheckNeeded() && |
| 4874 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { | 4827 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { |
| 4875 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); | 4828 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); |
| 4876 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 4829 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 4877 return factory->false_value(); | 4830 return factory->false_value(); |
| 4878 } | 4831 } |
| 4879 | 4832 |
| 4880 if (object->IsStringObjectWithCharacterAt(index)) { | 4833 if (object->IsStringObjectWithCharacterAt(index)) { |
| 4881 if (mode == STRICT_DELETION) { | 4834 if (strict_mode == STRICT) { |
| 4882 // Deleting a non-configurable property in strict mode. | 4835 // Deleting a non-configurable property in strict mode. |
| 4883 Handle<Object> name = factory->NewNumberFromUint(index); | 4836 Handle<Object> name = factory->NewNumberFromUint(index); |
| 4884 Handle<Object> args[2] = { name, object }; | 4837 Handle<Object> args[2] = { name, object }; |
| 4885 THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", | 4838 THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", |
| 4886 HandleVector(args, 2)), | 4839 HandleVector(args, 2)), |
| 4887 Object); | 4840 Object); |
| 4888 } | 4841 } |
| 4889 return factory->false_value(); | 4842 return factory->false_value(); |
| 4890 } | 4843 } |
| 4891 | 4844 |
| 4892 if (object->IsJSGlobalProxy()) { | 4845 if (object->IsJSGlobalProxy()) { |
| 4893 PrototypeIterator iter(isolate, object); | 4846 PrototypeIterator iter(isolate, object); |
| 4894 if (iter.IsAtEnd()) return factory->false_value(); | 4847 if (iter.IsAtEnd()) return factory->false_value(); |
| 4895 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 4848 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 4896 return DeleteElement( | 4849 return DeleteElement( |
| 4897 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, | 4850 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, |
| 4898 mode); | 4851 strict_mode); |
| 4899 } | 4852 } |
| 4900 | 4853 |
| 4901 Handle<Object> old_value; | 4854 Handle<Object> old_value; |
| 4902 bool should_enqueue_change_record = false; | 4855 bool should_enqueue_change_record = false; |
| 4903 if (object->map()->is_observed()) { | 4856 if (object->map()->is_observed()) { |
| 4904 Maybe<bool> maybe = HasOwnElement(object, index); | 4857 Maybe<bool> maybe = HasOwnElement(object, index); |
| 4905 if (!maybe.has_value) return MaybeHandle<Object>(); | 4858 if (!maybe.has_value) return MaybeHandle<Object>(); |
| 4906 should_enqueue_change_record = maybe.value; | 4859 should_enqueue_change_record = maybe.value; |
| 4907 if (should_enqueue_change_record) { | 4860 if (should_enqueue_change_record) { |
| 4908 if (!GetOwnElementAccessorPair(object, index).is_null()) { | 4861 if (!GetOwnElementAccessorPair(object, index).is_null()) { |
| 4909 old_value = Handle<Object>::cast(factory->the_hole_value()); | 4862 old_value = Handle<Object>::cast(factory->the_hole_value()); |
| 4910 } else { | 4863 } else { |
| 4911 old_value = Object::GetElement( | 4864 old_value = Object::GetElement( |
| 4912 isolate, object, index).ToHandleChecked(); | 4865 isolate, object, index).ToHandleChecked(); |
| 4913 } | 4866 } |
| 4914 } | 4867 } |
| 4915 } | 4868 } |
| 4916 | 4869 |
| 4917 // Skip interceptor if forcing deletion. | 4870 // Skip interceptor if forcing deletion. |
| 4918 MaybeHandle<Object> maybe_result; | 4871 MaybeHandle<Object> maybe_result; |
| 4919 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { | 4872 if (object->HasIndexedInterceptor()) { |
| 4920 maybe_result = DeleteElementWithInterceptor(object, index); | 4873 maybe_result = DeleteElementWithInterceptor(object, index); |
| 4921 } else { | 4874 } else { |
| 4922 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); | 4875 maybe_result = |
| 4876 object->GetElementsAccessor()->Delete(object, index, strict_mode); |
| 4923 } | 4877 } |
| 4924 Handle<Object> result; | 4878 Handle<Object> result; |
| 4925 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); | 4879 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); |
| 4926 | 4880 |
| 4927 if (should_enqueue_change_record) { | 4881 if (should_enqueue_change_record) { |
| 4928 Maybe<bool> maybe = HasOwnElement(object, index); | 4882 Maybe<bool> maybe = HasOwnElement(object, index); |
| 4929 if (!maybe.has_value) return MaybeHandle<Object>(); | 4883 if (!maybe.has_value) return MaybeHandle<Object>(); |
| 4930 if (!maybe.value) { | 4884 if (!maybe.value) { |
| 4931 Handle<String> name = factory->Uint32ToString(index); | 4885 Handle<String> name = factory->Uint32ToString(index); |
| 4932 RETURN_ON_EXCEPTION( | 4886 RETURN_ON_EXCEPTION( |
| 4933 isolate, EnqueueChangeRecord(object, "delete", name, old_value), | 4887 isolate, EnqueueChangeRecord(object, "delete", name, old_value), |
| 4934 Object); | 4888 Object); |
| 4935 } | 4889 } |
| 4936 } | 4890 } |
| 4937 | 4891 |
| 4938 return result; | 4892 return result; |
| 4939 } | 4893 } |
| 4940 | 4894 |
| 4941 | 4895 |
| 4896 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
| 4897 Handle<Name> name) { |
| 4898 DCHECK(!object->HasFastProperties()); |
| 4899 Isolate* isolate = object->GetIsolate(); |
| 4900 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 4901 int entry = dictionary->FindEntry(name); |
| 4902 DCHECK_NE(NameDictionary::kNotFound, entry); |
| 4903 |
| 4904 // If we have a global object set the cell to the hole. |
| 4905 if (object->IsGlobalObject()) { |
| 4906 PropertyDetails details = dictionary->DetailsAt(entry); |
| 4907 DCHECK(details.IsConfigurable()); |
| 4908 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 4909 Handle<Object> value = isolate->factory()->the_hole_value(); |
| 4910 PropertyCell::SetValueInferType(cell, value); |
| 4911 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 4912 return; |
| 4913 } |
| 4914 |
| 4915 NameDictionary::DeleteProperty(dictionary, entry); |
| 4916 Handle<NameDictionary> new_properties = |
| 4917 NameDictionary::Shrink(dictionary, name); |
| 4918 object->set_properties(*new_properties); |
| 4919 } |
| 4920 |
| 4921 |
| 4942 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 4922 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
| 4943 Handle<Name> name, | 4923 Handle<Name> name, |
| 4944 DeleteMode delete_mode) { | 4924 StrictMode strict_mode) { |
| 4945 // ECMA-262, 3rd, 8.6.2.5 | 4925 // ECMA-262, 3rd, 8.6.2.5 |
| 4946 DCHECK(name->IsName()); | 4926 DCHECK(name->IsName()); |
| 4947 | 4927 |
| 4948 uint32_t index = 0; | 4928 uint32_t index = 0; |
| 4949 if (name->AsArrayIndex(&index)) { | 4929 if (name->AsArrayIndex(&index)) { |
| 4950 return DeleteElement(object, index, delete_mode); | 4930 return DeleteElement(object, index, strict_mode); |
| 4951 } | 4931 } |
| 4952 | 4932 |
| 4953 // Skip interceptors on FORCE_DELETION. | 4933 LookupIterator it(object, name, LookupIterator::HIDDEN); |
| 4954 LookupIterator::Configuration config = | |
| 4955 delete_mode == FORCE_DELETION ? LookupIterator::HIDDEN_SKIP_INTERCEPTOR | |
| 4956 : LookupIterator::HIDDEN; | |
| 4957 | |
| 4958 LookupIterator it(object, name, config); | |
| 4959 | 4934 |
| 4960 bool is_observed = object->map()->is_observed() && | 4935 bool is_observed = object->map()->is_observed() && |
| 4961 !it.isolate()->IsInternallyUsedPropertyName(name); | 4936 !it.isolate()->IsInternallyUsedPropertyName(name); |
| 4962 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); | 4937 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
| 4963 | 4938 |
| 4964 for (; it.IsFound(); it.Next()) { | 4939 for (; it.IsFound(); it.Next()) { |
| 4965 switch (it.state()) { | 4940 switch (it.state()) { |
| 4966 case LookupIterator::JSPROXY: | 4941 case LookupIterator::JSPROXY: |
| 4967 case LookupIterator::NOT_FOUND: | 4942 case LookupIterator::NOT_FOUND: |
| 4968 case LookupIterator::TRANSITION: | 4943 case LookupIterator::TRANSITION: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4982 // An exception was thrown in the interceptor. Propagate. | 4957 // An exception was thrown in the interceptor. Propagate. |
| 4983 if (it.isolate()->has_pending_exception()) return maybe_result; | 4958 if (it.isolate()->has_pending_exception()) return maybe_result; |
| 4984 break; | 4959 break; |
| 4985 } | 4960 } |
| 4986 case LookupIterator::DATA: | 4961 case LookupIterator::DATA: |
| 4987 if (is_observed) { | 4962 if (is_observed) { |
| 4988 old_value = it.GetDataValue(); | 4963 old_value = it.GetDataValue(); |
| 4989 } | 4964 } |
| 4990 // Fall through. | 4965 // Fall through. |
| 4991 case LookupIterator::ACCESSOR: { | 4966 case LookupIterator::ACCESSOR: { |
| 4992 if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) { | 4967 if (!it.IsConfigurable()) { |
| 4993 // Fail if the property is not configurable. | 4968 // Fail if the property is not configurable. |
| 4994 if (delete_mode == STRICT_DELETION) { | 4969 if (strict_mode == STRICT) { |
| 4995 Handle<Object> args[2] = {name, object}; | 4970 Handle<Object> args[2] = {name, object}; |
| 4996 THROW_NEW_ERROR(it.isolate(), | 4971 THROW_NEW_ERROR(it.isolate(), |
| 4997 NewTypeError("strict_delete_property", | 4972 NewTypeError("strict_delete_property", |
| 4998 HandleVector(args, arraysize(args))), | 4973 HandleVector(args, arraysize(args))), |
| 4999 Object); | 4974 Object); |
| 5000 } | 4975 } |
| 5001 return it.isolate()->factory()->false_value(); | 4976 return it.isolate()->factory()->false_value(); |
| 5002 } | 4977 } |
| 5003 | 4978 |
| 5004 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 4979 PropertyNormalizationMode mode = object->map()->is_prototype_map() |
| 5005 ? KEEP_INOBJECT_PROPERTIES | 4980 ? KEEP_INOBJECT_PROPERTIES |
| 5006 : CLEAR_INOBJECT_PROPERTIES; | 4981 : CLEAR_INOBJECT_PROPERTIES; |
| 5007 Handle<JSObject> holder = it.GetHolder<JSObject>(); | 4982 Handle<JSObject> holder = it.GetHolder<JSObject>(); |
| 5008 // TODO(verwaest): Remove this temporary compatibility hack when blink | 4983 // TODO(verwaest): Remove this temporary compatibility hack when blink |
| 5009 // tests are updated. | 4984 // tests are updated. |
| 5010 if (!holder.is_identical_to(object) && | 4985 if (!holder.is_identical_to(object) && |
| 5011 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { | 4986 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { |
| 5012 return it.isolate()->factory()->true_value(); | 4987 return it.isolate()->factory()->true_value(); |
| 5013 } | 4988 } |
| 4989 |
| 5014 NormalizeProperties(holder, mode, 0, "DeletingProperty"); | 4990 NormalizeProperties(holder, mode, 0, "DeletingProperty"); |
| 5015 Handle<Object> result = | 4991 DeleteNormalizedProperty(holder, name); |
| 5016 DeleteNormalizedProperty(holder, name, delete_mode); | |
| 5017 ReoptimizeIfPrototype(holder); | 4992 ReoptimizeIfPrototype(holder); |
| 5018 | 4993 |
| 5019 if (is_observed) { | 4994 if (is_observed) { |
| 5020 RETURN_ON_EXCEPTION( | 4995 RETURN_ON_EXCEPTION( |
| 5021 it.isolate(), | 4996 it.isolate(), |
| 5022 EnqueueChangeRecord(object, "delete", name, old_value), Object); | 4997 EnqueueChangeRecord(object, "delete", name, old_value), Object); |
| 5023 } | 4998 } |
| 5024 | 4999 |
| 5025 return result; | 5000 return it.isolate()->factory()->true_value(); |
| 5026 } | 5001 } |
| 5027 } | 5002 } |
| 5028 } | 5003 } |
| 5029 | 5004 |
| 5030 return it.isolate()->factory()->true_value(); | 5005 return it.isolate()->factory()->true_value(); |
| 5031 } | 5006 } |
| 5032 | 5007 |
| 5033 | 5008 |
| 5034 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, | 5009 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, |
| 5035 uint32_t index, | 5010 uint32_t index, |
| 5036 DeleteMode mode) { | 5011 StrictMode strict_mode) { |
| 5037 if (object->IsJSProxy()) { | 5012 if (object->IsJSProxy()) { |
| 5038 return JSProxy::DeleteElementWithHandler( | 5013 return JSProxy::DeleteElementWithHandler(Handle<JSProxy>::cast(object), |
| 5039 Handle<JSProxy>::cast(object), index, mode); | 5014 index, strict_mode); |
| 5040 } | 5015 } |
| 5041 return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, mode); | 5016 return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, |
| 5017 strict_mode); |
| 5042 } | 5018 } |
| 5043 | 5019 |
| 5044 | 5020 |
| 5045 MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, | 5021 MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, |
| 5046 Handle<Name> name, | 5022 Handle<Name> name, |
| 5047 DeleteMode mode) { | 5023 StrictMode strict_mode) { |
| 5048 if (object->IsJSProxy()) { | 5024 if (object->IsJSProxy()) { |
| 5049 return JSProxy::DeletePropertyWithHandler( | 5025 return JSProxy::DeletePropertyWithHandler(Handle<JSProxy>::cast(object), |
| 5050 Handle<JSProxy>::cast(object), name, mode); | 5026 name, strict_mode); |
| 5051 } | 5027 } |
| 5052 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode); | 5028 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, |
| 5029 strict_mode); |
| 5053 } | 5030 } |
| 5054 | 5031 |
| 5055 | 5032 |
| 5056 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 5033 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 5057 ElementsKind kind, | 5034 ElementsKind kind, |
| 5058 Object* object) { | 5035 Object* object) { |
| 5059 DCHECK(IsFastObjectElementsKind(kind) || | 5036 DCHECK(IsFastObjectElementsKind(kind) || |
| 5060 kind == DICTIONARY_ELEMENTS); | 5037 kind == DICTIONARY_ELEMENTS); |
| 5061 if (IsFastObjectElementsKind(kind)) { | 5038 if (IsFastObjectElementsKind(kind)) { |
| 5062 int length = IsJSArray() | 5039 int length = IsJSArray() |
| (...skipping 9399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14462 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14439 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14463 CopyKeysTo( | 14440 CopyKeysTo( |
| 14464 FixedArray*, | 14441 FixedArray*, |
| 14465 PropertyAttributes, | 14442 PropertyAttributes, |
| 14466 Dictionary<SeededNumberDictionary, | 14443 Dictionary<SeededNumberDictionary, |
| 14467 SeededNumberDictionaryShape, | 14444 SeededNumberDictionaryShape, |
| 14468 uint32_t>::SortMode); | 14445 uint32_t>::SortMode); |
| 14469 | 14446 |
| 14470 template Handle<Object> | 14447 template Handle<Object> |
| 14471 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty( | 14448 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty( |
| 14472 Handle<NameDictionary>, int, JSObject::DeleteMode); | 14449 Handle<NameDictionary>, int); |
| 14473 | 14450 |
| 14474 template Handle<Object> | 14451 template Handle<Object> |
| 14475 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14452 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, |
| 14476 DeleteProperty(Handle<SeededNumberDictionary>, int, JSObject::DeleteMode); | 14453 uint32_t>::DeleteProperty(Handle<SeededNumberDictionary>, int); |
| 14477 | 14454 |
| 14478 template Handle<NameDictionary> | 14455 template Handle<NameDictionary> |
| 14479 HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >:: | 14456 HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
| 14480 New(Isolate*, int, MinimumCapacity, PretenureFlag); | 14457 New(Isolate*, int, MinimumCapacity, PretenureFlag); |
| 14481 | 14458 |
| 14482 template Handle<NameDictionary> | 14459 template Handle<NameDictionary> |
| 14483 HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >:: | 14460 HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
| 14484 Shrink(Handle<NameDictionary>, Handle<Name>); | 14461 Shrink(Handle<NameDictionary>, Handle<Name>); |
| 14485 | 14462 |
| 14486 template Handle<SeededNumberDictionary> | 14463 template Handle<SeededNumberDictionary> |
| (...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15444 // Check whether there are enough enumeration indices to add n elements. | 15421 // Check whether there are enough enumeration indices to add n elements. |
| 15445 if (Shape::kIsEnumerable && | 15422 if (Shape::kIsEnumerable && |
| 15446 !PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) { | 15423 !PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) { |
| 15447 // If not, we generate new indices for the properties. | 15424 // If not, we generate new indices for the properties. |
| 15448 GenerateNewEnumerationIndices(dictionary); | 15425 GenerateNewEnumerationIndices(dictionary); |
| 15449 } | 15426 } |
| 15450 return DerivedHashTable::EnsureCapacity(dictionary, n, key); | 15427 return DerivedHashTable::EnsureCapacity(dictionary, n, key); |
| 15451 } | 15428 } |
| 15452 | 15429 |
| 15453 | 15430 |
| 15454 template<typename Derived, typename Shape, typename Key> | 15431 template <typename Derived, typename Shape, typename Key> |
| 15455 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( | 15432 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( |
| 15456 Handle<Derived> dictionary, | 15433 Handle<Derived> dictionary, int entry) { |
| 15457 int entry, | |
| 15458 JSObject::DeleteMode mode) { | |
| 15459 Factory* factory = dictionary->GetIsolate()->factory(); | 15434 Factory* factory = dictionary->GetIsolate()->factory(); |
| 15460 PropertyDetails details = dictionary->DetailsAt(entry); | 15435 PropertyDetails details = dictionary->DetailsAt(entry); |
| 15461 // Ignore attributes if forcing a deletion. | 15436 if (!details.IsConfigurable()) return factory->false_value(); |
| 15462 if (!details.IsConfigurable() && mode != JSReceiver::FORCE_DELETION) { | |
| 15463 return factory->false_value(); | |
| 15464 } | |
| 15465 | 15437 |
| 15466 dictionary->SetEntry( | 15438 dictionary->SetEntry( |
| 15467 entry, factory->the_hole_value(), factory->the_hole_value()); | 15439 entry, factory->the_hole_value(), factory->the_hole_value()); |
| 15468 dictionary->ElementRemoved(); | 15440 dictionary->ElementRemoved(); |
| 15469 return factory->true_value(); | 15441 return factory->true_value(); |
| 15470 } | 15442 } |
| 15471 | 15443 |
| 15472 | 15444 |
| 15473 template<typename Derived, typename Shape, typename Key> | 15445 template<typename Derived, typename Shape, typename Key> |
| 15474 Handle<Derived> Dictionary<Derived, Shape, Key>::AtPut( | 15446 Handle<Derived> Dictionary<Derived, Shape, Key>::AtPut( |
| (...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16829 Handle<DependentCode> codes = | 16801 Handle<DependentCode> codes = |
| 16830 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16802 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16831 DependentCode::kPropertyCellChangedGroup, | 16803 DependentCode::kPropertyCellChangedGroup, |
| 16832 info->object_wrapper()); | 16804 info->object_wrapper()); |
| 16833 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16805 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16834 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16806 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16835 cell, info->zone()); | 16807 cell, info->zone()); |
| 16836 } | 16808 } |
| 16837 | 16809 |
| 16838 } } // namespace v8::internal | 16810 } } // namespace v8::internal |
| OLD | NEW |