| 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 |