OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 cell->set_value(value); | 694 cell->set_value(value); |
695 // Please note we have to update the property details. | 695 // Please note we have to update the property details. |
696 property_dictionary()->DetailsAtPut(entry, details); | 696 property_dictionary()->DetailsAtPut(entry, details); |
697 } else { | 697 } else { |
698 property_dictionary()->SetEntry(entry, name, value, details); | 698 property_dictionary()->SetEntry(entry, name, value, details); |
699 } | 699 } |
700 return value; | 700 return value; |
701 } | 701 } |
702 | 702 |
703 | 703 |
704 MaybeObject* JSObject::DeleteNormalizedProperty(Name* name, DeleteMode mode) { | 704 // TODO(mstarzinger): Temporary wrapper until target is handlified. |
705 ASSERT(!HasFastProperties()); | 705 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict, |
706 NameDictionary* dictionary = property_dictionary(); | 706 Handle<Name> name) { |
707 int entry = dictionary->FindEntry(name); | 707 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); |
| 708 } |
| 709 |
| 710 |
| 711 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
| 712 Handle<Name> name, |
| 713 DeleteMode mode) { |
| 714 ASSERT(!object->HasFastProperties()); |
| 715 Isolate* isolate = object->GetIsolate(); |
| 716 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 717 int entry = dictionary->FindEntry(*name); |
708 if (entry != NameDictionary::kNotFound) { | 718 if (entry != NameDictionary::kNotFound) { |
709 // If we have a global object set the cell to the hole. | 719 // If we have a global object set the cell to the hole. |
710 if (IsGlobalObject()) { | 720 if (object->IsGlobalObject()) { |
711 PropertyDetails details = dictionary->DetailsAt(entry); | 721 PropertyDetails details = dictionary->DetailsAt(entry); |
712 if (details.IsDontDelete()) { | 722 if (details.IsDontDelete()) { |
713 if (mode != FORCE_DELETION) return GetHeap()->false_value(); | 723 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
714 // When forced to delete global properties, we have to make a | 724 // When forced to delete global properties, we have to make a |
715 // map change to invalidate any ICs that think they can load | 725 // map change to invalidate any ICs that think they can load |
716 // from the DontDelete cell without checking if it contains | 726 // from the DontDelete cell without checking if it contains |
717 // the hole value. | 727 // the hole value. |
718 Map* new_map; | 728 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
719 MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | |
720 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
721 | |
722 ASSERT(new_map->is_dictionary_map()); | 729 ASSERT(new_map->is_dictionary_map()); |
723 set_map(new_map); | 730 object->set_map(*new_map); |
724 } | 731 } |
725 PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry)); | 732 PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry)); |
726 cell->set_value(cell->GetHeap()->the_hole_value()); | 733 cell->set_value(isolate->heap()->the_hole_value()); |
727 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 734 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
728 } else { | 735 } else { |
729 Object* deleted = dictionary->DeleteProperty(entry, mode); | 736 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); |
730 if (deleted == GetHeap()->true_value()) { | 737 if (*deleted == isolate->heap()->true_value()) { |
731 FixedArray* new_properties = NULL; | 738 Handle<NameDictionary> new_properties = |
732 MaybeObject* maybe_properties = dictionary->Shrink(name); | 739 NameDictionaryShrink(dictionary, name); |
733 if (!maybe_properties->To(&new_properties)) { | 740 object->set_properties(*new_properties); |
734 return maybe_properties; | |
735 } | |
736 set_properties(new_properties); | |
737 } | 741 } |
738 return deleted; | 742 return deleted; |
739 } | 743 } |
740 } | 744 } |
741 return GetHeap()->true_value(); | 745 return isolate->factory()->true_value(); |
742 } | 746 } |
743 | 747 |
744 | 748 |
745 bool JSObject::IsDirty() { | 749 bool JSObject::IsDirty() { |
746 Object* cons_obj = map()->constructor(); | 750 Object* cons_obj = map()->constructor(); |
747 if (!cons_obj->IsJSFunction()) | 751 if (!cons_obj->IsJSFunction()) |
748 return true; | 752 return true; |
749 JSFunction* fun = JSFunction::cast(cons_obj); | 753 JSFunction* fun = JSFunction::cast(cons_obj); |
750 if (!fun->shared()->IsApiFunction()) | 754 if (!fun->shared()->IsApiFunction()) |
751 return true; | 755 return true; |
(...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3503 } | 3507 } |
3504 | 3508 |
3505 if (strict_mode == kNonStrictMode) return *value; | 3509 if (strict_mode == kNonStrictMode) return *value; |
3506 Handle<Object> args2[] = { name, proxy }; | 3510 Handle<Object> args2[] = { name, proxy }; |
3507 Handle<Object> error = isolate->factory()->NewTypeError( | 3511 Handle<Object> error = isolate->factory()->NewTypeError( |
3508 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | 3512 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); |
3509 return isolate->Throw(*error); | 3513 return isolate->Throw(*error); |
3510 } | 3514 } |
3511 | 3515 |
3512 | 3516 |
3513 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( | 3517 Handle<Object> JSProxy::DeletePropertyWithHandler( |
3514 Name* name_raw, DeleteMode mode) { | 3518 Handle<JSProxy> object, Handle<Name> name, DeleteMode mode) { |
3515 Isolate* isolate = GetIsolate(); | 3519 Isolate* isolate = object->GetIsolate(); |
3516 HandleScope scope(isolate); | |
3517 Handle<JSProxy> receiver(this); | |
3518 Handle<Object> name(name_raw, isolate); | |
3519 | 3520 |
3520 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3521 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
3521 if (name->IsSymbol()) return isolate->heap()->false_value(); | 3522 if (name->IsSymbol()) return isolate->factory()->false_value(); |
3522 | 3523 |
3523 Handle<Object> args[] = { name }; | 3524 Handle<Object> args[] = { name }; |
3524 Handle<Object> result = CallTrap( | 3525 Handle<Object> result = object->CallTrap( |
3525 "delete", Handle<Object>(), ARRAY_SIZE(args), args); | 3526 "delete", Handle<Object>(), ARRAY_SIZE(args), args); |
3526 if (isolate->has_pending_exception()) return Failure::Exception(); | 3527 if (isolate->has_pending_exception()) return Handle<Object>(); |
3527 | 3528 |
3528 bool result_bool = result->BooleanValue(); | 3529 bool result_bool = result->BooleanValue(); |
3529 if (mode == STRICT_DELETION && !result_bool) { | 3530 if (mode == STRICT_DELETION && !result_bool) { |
3530 Handle<Object> handler(receiver->handler(), isolate); | 3531 Handle<Object> handler(object->handler(), isolate); |
3531 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( | 3532 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( |
3532 STATIC_ASCII_VECTOR("delete")); | 3533 STATIC_ASCII_VECTOR("delete")); |
3533 Handle<Object> args[] = { handler, trap_name }; | 3534 Handle<Object> args[] = { handler, trap_name }; |
3534 Handle<Object> error = isolate->factory()->NewTypeError( | 3535 Handle<Object> error = isolate->factory()->NewTypeError( |
3535 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); | 3536 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); |
3536 isolate->Throw(*error); | 3537 isolate->Throw(*error); |
3537 return Failure::Exception(); | 3538 return Handle<Object>(); |
3538 } | 3539 } |
3539 return isolate->heap()->ToBoolean(result_bool); | 3540 return isolate->factory()->ToBoolean(result_bool); |
3540 } | 3541 } |
3541 | 3542 |
3542 | 3543 |
3543 MUST_USE_RESULT MaybeObject* JSProxy::DeleteElementWithHandler( | 3544 Handle<Object> JSProxy::DeleteElementWithHandler( |
3544 uint32_t index, | 3545 Handle<JSProxy> object, uint32_t index, DeleteMode mode) { |
3545 DeleteMode mode) { | 3546 Isolate* isolate = object->GetIsolate(); |
3546 Isolate* isolate = GetIsolate(); | |
3547 HandleScope scope(isolate); | |
3548 Handle<String> name = isolate->factory()->Uint32ToString(index); | 3547 Handle<String> name = isolate->factory()->Uint32ToString(index); |
3549 return JSProxy::DeletePropertyWithHandler(*name, mode); | 3548 return JSProxy::DeletePropertyWithHandler(object, name, mode); |
3550 } | 3549 } |
3551 | 3550 |
3552 | 3551 |
3553 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( | 3552 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( |
3554 JSReceiver* receiver_raw, | 3553 JSReceiver* receiver_raw, |
3555 Name* name_raw) { | 3554 Name* name_raw) { |
3556 Isolate* isolate = GetIsolate(); | 3555 Isolate* isolate = GetIsolate(); |
3557 HandleScope scope(isolate); | 3556 HandleScope scope(isolate); |
3558 Handle<JSProxy> proxy(this); | 3557 Handle<JSProxy> proxy(this); |
3559 Handle<Object> handler(this->handler(), isolate); // Trap might morph proxy. | 3558 Handle<Object> handler(this->handler(), isolate); // Trap might morph proxy. |
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4940 SetPropertyPostInterceptor(GetHeap()->hidden_string(), | 4939 SetPropertyPostInterceptor(GetHeap()->hidden_string(), |
4941 value, | 4940 value, |
4942 DONT_ENUM, | 4941 DONT_ENUM, |
4943 kNonStrictMode, | 4942 kNonStrictMode, |
4944 OMIT_EXTENSIBILITY_CHECK); | 4943 OMIT_EXTENSIBILITY_CHECK); |
4945 if (store_result->IsFailure()) return store_result; | 4944 if (store_result->IsFailure()) return store_result; |
4946 return this; | 4945 return this; |
4947 } | 4946 } |
4948 | 4947 |
4949 | 4948 |
4950 MaybeObject* JSObject::DeletePropertyPostInterceptor(Name* name, | 4949 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, |
4951 DeleteMode mode) { | 4950 Handle<Name> name, |
| 4951 DeleteMode mode) { |
4952 // Check local property, ignore interceptor. | 4952 // Check local property, ignore interceptor. |
4953 LookupResult result(GetIsolate()); | 4953 Isolate* isolate = object->GetIsolate(); |
4954 LocalLookupRealNamedProperty(name, &result); | 4954 LookupResult result(isolate); |
4955 if (!result.IsFound()) return GetHeap()->true_value(); | 4955 object->LocalLookupRealNamedProperty(*name, &result); |
| 4956 if (!result.IsFound()) return isolate->factory()->true_value(); |
4956 | 4957 |
4957 // Normalize object if needed. | 4958 // Normalize object if needed. |
4958 Object* obj; | 4959 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
4959 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | |
4960 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
4961 } | |
4962 | 4960 |
4963 return DeleteNormalizedProperty(name, mode); | 4961 return DeleteNormalizedProperty(object, name, mode); |
4964 } | 4962 } |
4965 | 4963 |
4966 | 4964 |
4967 MaybeObject* JSObject::DeletePropertyWithInterceptor(Name* name) { | 4965 Handle<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object, |
| 4966 Handle<Name> name) { |
| 4967 Isolate* isolate = object->GetIsolate(); |
| 4968 |
4968 // TODO(rossberg): Support symbols in the API. | 4969 // TODO(rossberg): Support symbols in the API. |
4969 if (name->IsSymbol()) return GetHeap()->false_value(); | 4970 if (name->IsSymbol()) return isolate->factory()->false_value(); |
4970 | 4971 |
4971 Isolate* isolate = GetIsolate(); | 4972 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); |
4972 HandleScope scope(isolate); | |
4973 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | |
4974 Handle<String> name_handle(String::cast(name)); | |
4975 Handle<JSObject> this_handle(this); | |
4976 if (!interceptor->deleter()->IsUndefined()) { | 4973 if (!interceptor->deleter()->IsUndefined()) { |
4977 v8::NamedPropertyDeleter deleter = | 4974 v8::NamedPropertyDeleter deleter = |
4978 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); | 4975 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); |
4979 LOG(isolate, | 4976 LOG(isolate, |
4980 ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); | 4977 ApiNamedPropertyAccess("interceptor-named-delete", *object, *name)); |
4981 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); | 4978 PropertyCallbackArguments args( |
| 4979 isolate, interceptor->data(), *object, *object); |
4982 v8::Handle<v8::Boolean> result = | 4980 v8::Handle<v8::Boolean> result = |
4983 args.Call(deleter, v8::Utils::ToLocal(name_handle)); | 4981 args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name))); |
4984 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 4982 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
4985 if (!result.IsEmpty()) { | 4983 if (!result.IsEmpty()) { |
4986 ASSERT(result->IsBoolean()); | 4984 ASSERT(result->IsBoolean()); |
4987 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 4985 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
4988 result_internal->VerifyApiCallResultType(); | 4986 result_internal->VerifyApiCallResultType(); |
4989 return *result_internal; | 4987 // Rebox CustomArguments::kReturnValueOffset before returning. |
| 4988 return handle(*result_internal, isolate); |
4990 } | 4989 } |
4991 } | 4990 } |
4992 MaybeObject* raw_result = | 4991 Handle<Object> result = |
4993 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); | 4992 DeletePropertyPostInterceptor(object, name, NORMAL_DELETION); |
4994 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 4993 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
4995 return raw_result; | 4994 return result; |
4996 } | 4995 } |
4997 | 4996 |
4998 | 4997 |
4999 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { | 4998 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { |
5000 Isolate* isolate = GetIsolate(); | 4999 Isolate* isolate = GetIsolate(); |
5001 Heap* heap = isolate->heap(); | 5000 Heap* heap = isolate->heap(); |
5002 // Make sure that the top context does not change when doing | 5001 // Make sure that the top context does not change when doing |
5003 // callbacks or interceptor calls. | 5002 // callbacks or interceptor calls. |
5004 AssertNoContextChange ncc; | 5003 AssertNoContextChange ncc; |
5005 HandleScope scope(isolate); | 5004 HandleScope scope(isolate); |
(...skipping 16 matching lines...) Expand all Loading... |
5022 MaybeObject* raw_result = this_handle->GetElementsAccessor()->Delete( | 5021 MaybeObject* raw_result = this_handle->GetElementsAccessor()->Delete( |
5023 *this_handle, | 5022 *this_handle, |
5024 index, | 5023 index, |
5025 NORMAL_DELETION); | 5024 NORMAL_DELETION); |
5026 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 5025 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
5027 return raw_result; | 5026 return raw_result; |
5028 } | 5027 } |
5029 | 5028 |
5030 | 5029 |
5031 Handle<Object> JSObject::DeleteElement(Handle<JSObject> obj, | 5030 Handle<Object> JSObject::DeleteElement(Handle<JSObject> obj, |
5032 uint32_t index) { | 5031 uint32_t index, |
| 5032 DeleteMode mode) { |
5033 CALL_HEAP_FUNCTION(obj->GetIsolate(), | 5033 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
5034 obj->DeleteElement(index, JSObject::NORMAL_DELETION), | 5034 obj->DeleteElement(index, mode), |
5035 Object); | 5035 Object); |
5036 } | 5036 } |
5037 | 5037 |
5038 | 5038 |
5039 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { | 5039 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { |
5040 Isolate* isolate = GetIsolate(); | 5040 Isolate* isolate = GetIsolate(); |
5041 // Check access rights if needed. | 5041 // Check access rights if needed. |
5042 if (IsAccessCheckNeeded() && | 5042 if (IsAccessCheckNeeded() && |
5043 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { | 5043 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
5044 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 5044 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5095 | 5095 |
5096 if (should_enqueue_change_record && !self->HasLocalElement(index)) { | 5096 if (should_enqueue_change_record && !self->HasLocalElement(index)) { |
5097 Handle<String> name = isolate->factory()->Uint32ToString(index); | 5097 Handle<String> name = isolate->factory()->Uint32ToString(index); |
5098 EnqueueChangeRecord(self, "deleted", name, old_value); | 5098 EnqueueChangeRecord(self, "deleted", name, old_value); |
5099 } | 5099 } |
5100 | 5100 |
5101 return *hresult; | 5101 return *hresult; |
5102 } | 5102 } |
5103 | 5103 |
5104 | 5104 |
5105 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> obj, | 5105 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
5106 Handle<Name> prop) { | 5106 Handle<Name> name, |
5107 CALL_HEAP_FUNCTION(obj->GetIsolate(), | 5107 DeleteMode mode) { |
5108 obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION), | 5108 Isolate* isolate = object->GetIsolate(); |
5109 Object); | |
5110 } | |
5111 | |
5112 | |
5113 MaybeObject* JSObject::DeleteProperty(Name* name, DeleteMode mode) { | |
5114 Isolate* isolate = GetIsolate(); | |
5115 // ECMA-262, 3rd, 8.6.2.5 | 5109 // ECMA-262, 3rd, 8.6.2.5 |
5116 ASSERT(name->IsName()); | 5110 ASSERT(name->IsName()); |
5117 | 5111 |
5118 // Check access rights if needed. | 5112 // Check access rights if needed. |
5119 if (IsAccessCheckNeeded() && | 5113 if (object->IsAccessCheckNeeded() && |
5120 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { | 5114 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_DELETE)) { |
5121 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 5115 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_DELETE); |
5122 return isolate->heap()->false_value(); | 5116 return isolate->factory()->false_value(); |
5123 } | 5117 } |
5124 | 5118 |
5125 if (IsJSGlobalProxy()) { | 5119 if (object->IsJSGlobalProxy()) { |
5126 Object* proto = GetPrototype(); | 5120 Object* proto = object->GetPrototype(); |
5127 if (proto->IsNull()) return isolate->heap()->false_value(); | 5121 if (proto->IsNull()) return isolate->factory()->false_value(); |
5128 ASSERT(proto->IsJSGlobalObject()); | 5122 ASSERT(proto->IsJSGlobalObject()); |
5129 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); | 5123 return JSGlobalObject::DeleteProperty( |
| 5124 handle(JSGlobalObject::cast(proto)), name, mode); |
5130 } | 5125 } |
5131 | 5126 |
5132 uint32_t index = 0; | 5127 uint32_t index = 0; |
5133 if (name->AsArrayIndex(&index)) { | 5128 if (name->AsArrayIndex(&index)) { |
5134 return DeleteElement(index, mode); | 5129 return DeleteElement(object, index, mode); |
5135 } | 5130 } |
5136 | 5131 |
5137 LookupResult lookup(isolate); | 5132 LookupResult lookup(isolate); |
5138 LocalLookup(name, &lookup, true); | 5133 object->LocalLookup(*name, &lookup, true); |
5139 if (!lookup.IsFound()) return isolate->heap()->true_value(); | 5134 if (!lookup.IsFound()) return isolate->factory()->true_value(); |
5140 // Ignore attributes if forcing a deletion. | 5135 // Ignore attributes if forcing a deletion. |
5141 if (lookup.IsDontDelete() && mode != FORCE_DELETION) { | 5136 if (lookup.IsDontDelete() && mode != FORCE_DELETION) { |
5142 if (mode == STRICT_DELETION) { | 5137 if (mode == STRICT_DELETION) { |
5143 // Deleting a non-configurable property in strict mode. | 5138 // Deleting a non-configurable property in strict mode. |
5144 HandleScope scope(isolate); | 5139 Handle<Object> args[2] = { name, object }; |
5145 Handle<Object> args[2] = { Handle<Object>(name, isolate), | 5140 Handle<Object> error = isolate->factory()->NewTypeError( |
5146 Handle<Object>(this, isolate) }; | 5141 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); |
5147 return isolate->Throw(*isolate->factory()->NewTypeError( | 5142 isolate->Throw(*error); |
5148 "strict_delete_property", HandleVector(args, 2))); | 5143 return Handle<Object>(); |
5149 } | 5144 } |
5150 return isolate->heap()->false_value(); | 5145 return isolate->factory()->false_value(); |
5151 } | 5146 } |
5152 | 5147 |
5153 // From this point on everything needs to be handlified. | |
5154 HandleScope scope(isolate); | |
5155 Handle<JSObject> self(this); | |
5156 Handle<Name> hname(name); | |
5157 | |
5158 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 5148 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
5159 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 5149 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); |
5160 if (is_observed && lookup.IsDataProperty()) { | 5150 if (is_observed && lookup.IsDataProperty()) { |
5161 old_value = Object::GetProperty(self, hname); | 5151 old_value = Object::GetProperty(object, name); |
5162 } | 5152 } |
5163 MaybeObject* result; | 5153 Handle<Object> result; |
5164 | 5154 |
5165 // Check for interceptor. | 5155 // Check for interceptor. |
5166 if (lookup.IsInterceptor()) { | 5156 if (lookup.IsInterceptor()) { |
5167 // Skip interceptor if forcing a deletion. | 5157 // Skip interceptor if forcing a deletion. |
5168 if (mode == FORCE_DELETION) { | 5158 if (mode == FORCE_DELETION) { |
5169 result = self->DeletePropertyPostInterceptor(*hname, mode); | 5159 result = DeletePropertyPostInterceptor(object, name, mode); |
5170 } else { | 5160 } else { |
5171 result = self->DeletePropertyWithInterceptor(*hname); | 5161 result = DeletePropertyWithInterceptor(object, name); |
5172 } | 5162 } |
5173 } else { | 5163 } else { |
5174 // Normalize object if needed. | 5164 // Normalize object if needed. |
5175 Object* obj; | 5165 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
5176 result = self->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | |
5177 if (!result->To(&obj)) return result; | |
5178 // Make sure the properties are normalized before removing the entry. | 5166 // Make sure the properties are normalized before removing the entry. |
5179 result = self->DeleteNormalizedProperty(*hname, mode); | 5167 result = DeleteNormalizedProperty(object, name, mode); |
5180 } | 5168 } |
5181 | 5169 |
5182 Handle<Object> hresult; | 5170 if (is_observed && !object->HasLocalProperty(*name)) { |
5183 if (!result->ToHandle(&hresult, isolate)) return result; | 5171 EnqueueChangeRecord(object, "deleted", name, old_value); |
5184 | |
5185 if (is_observed && !self->HasLocalProperty(*hname)) { | |
5186 EnqueueChangeRecord(self, "deleted", hname, old_value); | |
5187 } | 5172 } |
5188 | 5173 |
5189 return *hresult; | 5174 return result; |
5190 } | 5175 } |
5191 | 5176 |
5192 | 5177 |
5193 MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) { | 5178 Handle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, |
5194 if (IsJSProxy()) { | 5179 uint32_t index, |
5195 return JSProxy::cast(this)->DeleteElementWithHandler(index, mode); | 5180 DeleteMode mode) { |
| 5181 if (object->IsJSProxy()) { |
| 5182 return JSProxy::DeleteElementWithHandler( |
| 5183 Handle<JSProxy>::cast(object), index, mode); |
5196 } | 5184 } |
5197 return JSObject::cast(this)->DeleteElement(index, mode); | 5185 return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, mode); |
5198 } | 5186 } |
5199 | 5187 |
5200 | 5188 |
5201 MaybeObject* JSReceiver::DeleteProperty(Name* name, DeleteMode mode) { | 5189 Handle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, |
5202 if (IsJSProxy()) { | 5190 Handle<Name> name, |
5203 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); | 5191 DeleteMode mode) { |
| 5192 if (object->IsJSProxy()) { |
| 5193 return JSProxy::DeletePropertyWithHandler( |
| 5194 Handle<JSProxy>::cast(object), name, mode); |
5204 } | 5195 } |
5205 return JSObject::cast(this)->DeleteProperty(name, mode); | 5196 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode); |
5206 } | 5197 } |
5207 | 5198 |
5208 | 5199 |
5209 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 5200 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
5210 ElementsKind kind, | 5201 ElementsKind kind, |
5211 Object* object) { | 5202 Object* object) { |
5212 ASSERT(IsFastObjectElementsKind(kind) || | 5203 ASSERT(IsFastObjectElementsKind(kind) || |
5213 kind == DICTIONARY_ELEMENTS); | 5204 kind == DICTIONARY_ELEMENTS); |
5214 if (IsFastObjectElementsKind(kind)) { | 5205 if (IsFastObjectElementsKind(kind)) { |
5215 int length = IsJSArray() | 5206 int length = IsJSArray() |
(...skipping 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6439 #ifdef VERIFY_HEAP | 6430 #ifdef VERIFY_HEAP |
6440 if (FLAG_verify_heap && result->is_shared()) { | 6431 if (FLAG_verify_heap && result->is_shared()) { |
6441 result->SharedMapVerify(); | 6432 result->SharedMapVerify(); |
6442 } | 6433 } |
6443 #endif | 6434 #endif |
6444 | 6435 |
6445 return result; | 6436 return result; |
6446 } | 6437 } |
6447 | 6438 |
6448 | 6439 |
| 6440 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { |
| 6441 CALL_HEAP_FUNCTION(map->GetIsolate(), map->CopyDropDescriptors(), Map); |
| 6442 } |
| 6443 |
| 6444 |
6449 MaybeObject* Map::CopyDropDescriptors() { | 6445 MaybeObject* Map::CopyDropDescriptors() { |
6450 Map* result; | 6446 Map* result; |
6451 MaybeObject* maybe_result = RawCopy(instance_size()); | 6447 MaybeObject* maybe_result = RawCopy(instance_size()); |
6452 if (!maybe_result->To(&result)) return maybe_result; | 6448 if (!maybe_result->To(&result)) return maybe_result; |
6453 | 6449 |
6454 // Please note instance_type and instance_size are set when allocated. | 6450 // Please note instance_type and instance_size are set when allocated. |
6455 result->set_inobject_properties(inobject_properties()); | 6451 result->set_inobject_properties(inobject_properties()); |
6456 result->set_unused_property_fields(unused_property_fields()); | 6452 result->set_unused_property_fields(unused_property_fields()); |
6457 | 6453 |
6458 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 6454 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); |
(...skipping 9359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15818 | 15814 |
15819 void PropertyCell::AddDependentCode(Handle<Code> code) { | 15815 void PropertyCell::AddDependentCode(Handle<Code> code) { |
15820 Handle<DependentCode> codes = DependentCode::Insert( | 15816 Handle<DependentCode> codes = DependentCode::Insert( |
15821 Handle<DependentCode>(dependent_code()), | 15817 Handle<DependentCode>(dependent_code()), |
15822 DependentCode::kPropertyCellChangedGroup, code); | 15818 DependentCode::kPropertyCellChangedGroup, code); |
15823 if (*codes != dependent_code()) set_dependent_code(*codes); | 15819 if (*codes != dependent_code()) set_dependent_code(*codes); |
15824 } | 15820 } |
15825 | 15821 |
15826 | 15822 |
15827 } } // namespace v8::internal | 15823 } } // namespace v8::internal |
OLD | NEW |