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 |