| 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 <iomanip> | 5 #include <iomanip> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 3921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3932 Handle<Object> handler(proxy->handler(), isolate); | 3932 Handle<Object> handler(proxy->handler(), isolate); |
| 3933 THROW_NEW_ERROR( | 3933 THROW_NEW_ERROR( |
| 3934 isolate, | 3934 isolate, |
| 3935 NewTypeError(MessageTemplate::kProxyHandlerDeleteFailed, handler), | 3935 NewTypeError(MessageTemplate::kProxyHandlerDeleteFailed, handler), |
| 3936 Object); | 3936 Object); |
| 3937 } | 3937 } |
| 3938 return isolate->factory()->ToBoolean(result_bool); | 3938 return isolate->factory()->ToBoolean(result_bool); |
| 3939 } | 3939 } |
| 3940 | 3940 |
| 3941 | 3941 |
| 3942 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( | |
| 3943 Handle<JSProxy> proxy, uint32_t index, LanguageMode language_mode) { | |
| 3944 Isolate* isolate = proxy->GetIsolate(); | |
| 3945 Handle<String> name = isolate->factory()->Uint32ToString(index); | |
| 3946 return JSProxy::DeletePropertyWithHandler(proxy, name, language_mode); | |
| 3947 } | |
| 3948 | |
| 3949 | |
| 3950 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler( | 3942 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler( |
| 3951 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) { | 3943 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) { |
| 3952 Isolate* isolate = proxy->GetIsolate(); | 3944 Isolate* isolate = proxy->GetIsolate(); |
| 3953 HandleScope scope(isolate); | 3945 HandleScope scope(isolate); |
| 3954 | 3946 |
| 3955 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3947 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3956 if (name->IsSymbol()) return Just(ABSENT); | 3948 if (name->IsSymbol()) return Just(ABSENT); |
| 3957 | 3949 |
| 3958 Handle<Object> args[] = { name }; | 3950 Handle<Object> args[] = { name }; |
| 3959 Handle<Object> result; | 3951 Handle<Object> result; |
| (...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5022 Handle<Object> value) { | 5014 Handle<Object> value) { |
| 5023 DCHECK(!object->IsJSGlobalProxy()); | 5015 DCHECK(!object->IsJSGlobalProxy()); |
| 5024 Isolate* isolate = object->GetIsolate(); | 5016 Isolate* isolate = object->GetIsolate(); |
| 5025 Handle<Name> name = isolate->factory()->hidden_string(); | 5017 Handle<Name> name = isolate->factory()->hidden_string(); |
| 5026 SetOwnPropertyIgnoreAttributes(object, name, value, DONT_ENUM).Assert(); | 5018 SetOwnPropertyIgnoreAttributes(object, name, value, DONT_ENUM).Assert(); |
| 5027 return object; | 5019 return object; |
| 5028 } | 5020 } |
| 5029 | 5021 |
| 5030 | 5022 |
| 5031 MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor( | 5023 MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor( |
| 5032 Handle<JSObject> holder, Handle<JSObject> receiver, Handle<Name> name) { | 5024 LookupIterator* it) { |
| 5033 Isolate* isolate = holder->GetIsolate(); | 5025 Isolate* isolate = it->isolate(); |
| 5026 // Make sure that the top context does not change when doing callbacks or |
| 5027 // interceptor calls. |
| 5028 AssertNoContextChange ncc(isolate); |
| 5034 | 5029 |
| 5035 Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor()); | 5030 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 5036 if (interceptor->deleter()->IsUndefined() || | 5031 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| 5037 (name->IsSymbol() && !interceptor->can_intercept_symbols())) { | 5032 if (interceptor->deleter()->IsUndefined()) return MaybeHandle<Object>(); |
| 5033 |
| 5034 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 5035 |
| 5036 PropertyCallbackArguments args(isolate, interceptor->data(), |
| 5037 *it->GetReceiver(), *holder); |
| 5038 v8::Handle<v8::Boolean> result; |
| 5039 if (it->IsElement()) { |
| 5040 uint32_t index = it->index(); |
| 5041 v8::IndexedPropertyDeleterCallback deleter = |
| 5042 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); |
| 5043 LOG(isolate, |
| 5044 ApiIndexedPropertyAccess("interceptor-indexed-delete", *holder, index)); |
| 5045 result = args.Call(deleter, index); |
| 5046 } else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) { |
| 5038 return MaybeHandle<Object>(); | 5047 return MaybeHandle<Object>(); |
| 5048 } else { |
| 5049 Handle<Name> name = it->name(); |
| 5050 v8::GenericNamedPropertyDeleterCallback deleter = |
| 5051 v8::ToCData<v8::GenericNamedPropertyDeleterCallback>( |
| 5052 interceptor->deleter()); |
| 5053 LOG(isolate, |
| 5054 ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name)); |
| 5055 result = args.Call(deleter, v8::Utils::ToLocal(name)); |
| 5039 } | 5056 } |
| 5040 | 5057 |
| 5041 v8::GenericNamedPropertyDeleterCallback deleter = | |
| 5042 v8::ToCData<v8::GenericNamedPropertyDeleterCallback>( | |
| 5043 interceptor->deleter()); | |
| 5044 LOG(isolate, | |
| 5045 ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name)); | |
| 5046 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, | |
| 5047 *holder); | |
| 5048 v8::Handle<v8::Boolean> result = args.Call(deleter, v8::Utils::ToLocal(name)); | |
| 5049 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5058 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5050 if (result.IsEmpty()) return MaybeHandle<Object>(); | 5059 if (result.IsEmpty()) return MaybeHandle<Object>(); |
| 5051 | 5060 |
| 5052 DCHECK(result->IsBoolean()); | 5061 DCHECK(result->IsBoolean()); |
| 5053 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 5062 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
| 5054 result_internal->VerifyApiCallResultType(); | 5063 result_internal->VerifyApiCallResultType(); |
| 5055 // Rebox CustomArguments::kReturnValueOffset before returning. | 5064 // Rebox CustomArguments::kReturnValueOffset before returning. |
| 5056 return handle(*result_internal, isolate); | 5065 return handle(*result_internal, isolate); |
| 5057 } | 5066 } |
| 5058 | 5067 |
| 5059 | 5068 |
| 5060 MaybeHandle<Object> JSObject::DeleteElementWithInterceptor( | |
| 5061 Handle<JSObject> object, | |
| 5062 uint32_t index) { | |
| 5063 Isolate* isolate = object->GetIsolate(); | |
| 5064 Factory* factory = isolate->factory(); | |
| 5065 | |
| 5066 // Make sure that the top context does not change when doing | |
| 5067 // callbacks or interceptor calls. | |
| 5068 AssertNoContextChange ncc(isolate); | |
| 5069 | |
| 5070 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); | |
| 5071 if (interceptor->deleter()->IsUndefined()) return factory->false_value(); | |
| 5072 v8::IndexedPropertyDeleterCallback deleter = | |
| 5073 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); | |
| 5074 LOG(isolate, | |
| 5075 ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index)); | |
| 5076 PropertyCallbackArguments args( | |
| 5077 isolate, interceptor->data(), *object, *object); | |
| 5078 v8::Handle<v8::Boolean> result = args.Call(deleter, index); | |
| 5079 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | |
| 5080 if (!result.IsEmpty()) { | |
| 5081 DCHECK(result->IsBoolean()); | |
| 5082 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | |
| 5083 result_internal->VerifyApiCallResultType(); | |
| 5084 // Rebox CustomArguments::kReturnValueOffset before returning. | |
| 5085 return handle(*result_internal, isolate); | |
| 5086 } | |
| 5087 // TODO(verwaest): Shouldn't this be the mode that was passed in? | |
| 5088 MaybeHandle<Object> delete_result = | |
| 5089 object->GetElementsAccessor()->Delete(object, index, SLOPPY); | |
| 5090 return delete_result; | |
| 5091 } | |
| 5092 | |
| 5093 | |
| 5094 MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, | |
| 5095 uint32_t index, | |
| 5096 LanguageMode language_mode) { | |
| 5097 Isolate* isolate = object->GetIsolate(); | |
| 5098 Factory* factory = isolate->factory(); | |
| 5099 | |
| 5100 // Check access rights if needed. | |
| 5101 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { | |
| 5102 isolate->ReportFailedAccessCheck(object); | |
| 5103 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | |
| 5104 return factory->false_value(); | |
| 5105 } | |
| 5106 | |
| 5107 if (object->IsStringObjectWithCharacterAt(index)) { | |
| 5108 if (is_strict(language_mode)) { | |
| 5109 // Deleting a non-configurable property in strict mode. | |
| 5110 Handle<Object> name = factory->NewNumberFromUint(index); | |
| 5111 THROW_NEW_ERROR( | |
| 5112 isolate, | |
| 5113 NewTypeError(MessageTemplate::kStrictDeleteProperty, name, object), | |
| 5114 Object); | |
| 5115 } | |
| 5116 return factory->false_value(); | |
| 5117 } | |
| 5118 | |
| 5119 if (object->IsJSGlobalProxy()) { | |
| 5120 PrototypeIterator iter(isolate, object); | |
| 5121 if (iter.IsAtEnd()) return factory->false_value(); | |
| 5122 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | |
| 5123 return DeleteElement( | |
| 5124 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, | |
| 5125 language_mode); | |
| 5126 } | |
| 5127 | |
| 5128 Handle<Object> old_value; | |
| 5129 bool should_enqueue_change_record = false; | |
| 5130 if (object->map()->is_observed()) { | |
| 5131 Maybe<bool> maybe = HasOwnElement(object, index); | |
| 5132 if (!maybe.IsJust()) return MaybeHandle<Object>(); | |
| 5133 should_enqueue_change_record = maybe.FromJust(); | |
| 5134 if (should_enqueue_change_record) { | |
| 5135 if (!GetOwnElementAccessorPair(object, index).is_null()) { | |
| 5136 old_value = Handle<Object>::cast(factory->the_hole_value()); | |
| 5137 } else { | |
| 5138 old_value = Object::GetElement( | |
| 5139 isolate, object, index).ToHandleChecked(); | |
| 5140 } | |
| 5141 } | |
| 5142 } | |
| 5143 | |
| 5144 // Skip interceptor if forcing deletion. | |
| 5145 MaybeHandle<Object> maybe_result; | |
| 5146 if (object->HasIndexedInterceptor()) { | |
| 5147 maybe_result = DeleteElementWithInterceptor(object, index); | |
| 5148 } else { | |
| 5149 maybe_result = | |
| 5150 object->GetElementsAccessor()->Delete(object, index, language_mode); | |
| 5151 } | |
| 5152 Handle<Object> result; | |
| 5153 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); | |
| 5154 | |
| 5155 if (should_enqueue_change_record) { | |
| 5156 Maybe<bool> maybe = HasOwnElement(object, index); | |
| 5157 if (!maybe.IsJust()) return MaybeHandle<Object>(); | |
| 5158 if (!maybe.FromJust()) { | |
| 5159 Handle<String> name = factory->Uint32ToString(index); | |
| 5160 RETURN_ON_EXCEPTION( | |
| 5161 isolate, EnqueueChangeRecord(object, "delete", name, old_value), | |
| 5162 Object); | |
| 5163 } | |
| 5164 } | |
| 5165 | |
| 5166 return result; | |
| 5167 } | |
| 5168 | |
| 5169 | |
| 5170 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 5069 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
| 5171 Handle<Name> name) { | 5070 Handle<Name> name) { |
| 5172 DCHECK(!object->HasFastProperties()); | 5071 DCHECK(!object->HasFastProperties()); |
| 5173 Isolate* isolate = object->GetIsolate(); | 5072 Isolate* isolate = object->GetIsolate(); |
| 5174 | 5073 |
| 5175 if (object->IsGlobalObject()) { | 5074 if (object->IsGlobalObject()) { |
| 5176 // If we have a global object, invalidate the cell and swap in a new one. | 5075 // If we have a global object, invalidate the cell and swap in a new one. |
| 5177 Handle<GlobalDictionary> dictionary(object->global_dictionary()); | 5076 Handle<GlobalDictionary> dictionary(object->global_dictionary()); |
| 5178 int entry = dictionary->FindEntry(name); | 5077 int entry = dictionary->FindEntry(name); |
| 5179 DCHECK_NE(GlobalDictionary::kNotFound, entry); | 5078 DCHECK_NE(GlobalDictionary::kNotFound, entry); |
| 5180 | 5079 |
| 5181 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); | 5080 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); |
| 5182 cell->set_value(isolate->heap()->the_hole_value()); | 5081 cell->set_value(isolate->heap()->the_hole_value()); |
| 5183 // TODO(dcarney): InvalidateForDelete | 5082 // TODO(dcarney): InvalidateForDelete |
| 5184 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type( | 5083 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type( |
| 5185 PropertyCellType::kInvalidated)); | 5084 PropertyCellType::kInvalidated)); |
| 5186 } else { | 5085 } else { |
| 5187 Handle<NameDictionary> dictionary(object->property_dictionary()); | 5086 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 5188 int entry = dictionary->FindEntry(name); | 5087 int entry = dictionary->FindEntry(name); |
| 5189 DCHECK_NE(NameDictionary::kNotFound, entry); | 5088 DCHECK_NE(NameDictionary::kNotFound, entry); |
| 5190 | 5089 |
| 5191 NameDictionary::DeleteProperty(dictionary, entry); | 5090 NameDictionary::DeleteProperty(dictionary, entry); |
| 5192 Handle<NameDictionary> new_properties = | 5091 Handle<NameDictionary> new_properties = |
| 5193 NameDictionary::Shrink(dictionary, name); | 5092 NameDictionary::Shrink(dictionary, name); |
| 5194 object->set_properties(*new_properties); | 5093 object->set_properties(*new_properties); |
| 5195 } | 5094 } |
| 5196 } | 5095 } |
| 5197 | 5096 |
| 5198 | 5097 |
| 5199 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 5098 // ECMA-262, 3rd, 8.6.2.5 |
| 5200 Handle<Name> name, | 5099 MaybeHandle<Object> JSReceiver::DeleteProperty(LookupIterator* it, |
| 5201 LanguageMode language_mode) { | 5100 LanguageMode language_mode) { |
| 5202 // ECMA-262, 3rd, 8.6.2.5 | 5101 Isolate* isolate = it->isolate(); |
| 5203 DCHECK(name->IsName()); | 5102 if (it->state() == LookupIterator::JSPROXY) { |
| 5204 | 5103 return JSProxy::DeletePropertyWithHandler(it->GetHolder<JSProxy>(), |
| 5205 uint32_t index = 0; | 5104 it->GetName(), language_mode); |
| 5206 if (name->AsArrayIndex(&index)) { | |
| 5207 return DeleteElement(object, index, language_mode); | |
| 5208 } | 5105 } |
| 5209 | 5106 |
| 5210 LookupIterator it(object, name, LookupIterator::HIDDEN); | 5107 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
| 5211 | 5108 |
| 5212 bool is_observed = object->map()->is_observed() && | 5109 bool is_observed = |
| 5213 !it.isolate()->IsInternallyUsedPropertyName(name); | 5110 receiver->map()->is_observed() && |
| 5214 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); | 5111 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name())); |
| 5215 | 5112 |
| 5216 for (; it.IsFound(); it.Next()) { | 5113 Handle<Object> old_value = it->factory()->the_hole_value(); |
| 5217 switch (it.state()) { | 5114 |
| 5115 for (; it->IsFound(); it->Next()) { |
| 5116 switch (it->state()) { |
| 5218 case LookupIterator::JSPROXY: | 5117 case LookupIterator::JSPROXY: |
| 5219 case LookupIterator::NOT_FOUND: | 5118 case LookupIterator::NOT_FOUND: |
| 5220 case LookupIterator::TRANSITION: | 5119 case LookupIterator::TRANSITION: |
| 5221 UNREACHABLE(); | 5120 UNREACHABLE(); |
| 5222 case LookupIterator::ACCESS_CHECK: | 5121 case LookupIterator::ACCESS_CHECK: |
| 5223 if (it.HasAccess()) break; | 5122 if (it->HasAccess()) break; |
| 5224 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>()); | 5123 isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>()); |
| 5225 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); | 5124 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5226 return it.isolate()->factory()->false_value(); | 5125 return it->factory()->false_value(); |
| 5227 case LookupIterator::INTERCEPTOR: { | 5126 case LookupIterator::INTERCEPTOR: { |
| 5228 MaybeHandle<Object> maybe_result = | 5127 MaybeHandle<Object> maybe_result = |
| 5229 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(), | 5128 JSObject::DeletePropertyWithInterceptor(it); |
| 5230 object, it.name()); | |
| 5231 // Delete with interceptor succeeded. Return result. | 5129 // Delete with interceptor succeeded. Return result. |
| 5232 if (!maybe_result.is_null()) return maybe_result; | 5130 if (!maybe_result.is_null()) return maybe_result; |
| 5233 // An exception was thrown in the interceptor. Propagate. | 5131 // An exception was thrown in the interceptor. Propagate. |
| 5234 if (it.isolate()->has_pending_exception()) return maybe_result; | 5132 if (isolate->has_pending_exception()) return maybe_result; |
| 5235 break; | 5133 break; |
| 5236 } | 5134 } |
| 5237 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 5135 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
| 5238 return it.isolate()->factory()->true_value(); | 5136 return it->factory()->true_value(); |
| 5239 case LookupIterator::DATA: | 5137 case LookupIterator::DATA: |
| 5240 if (is_observed) { | 5138 if (is_observed) { |
| 5241 old_value = it.GetDataValue(); | 5139 old_value = it->GetDataValue(); |
| 5242 } | 5140 } |
| 5243 // Fall through. | 5141 // Fall through. |
| 5244 case LookupIterator::ACCESSOR: { | 5142 case LookupIterator::ACCESSOR: { |
| 5245 if (!it.IsConfigurable() || object->map()->is_strong()) { | 5143 if (!it->IsConfigurable() || receiver->map()->is_strong()) { |
| 5246 // Fail if the property is not configurable, or on a strong object. | 5144 // Fail if the property is not configurable, or on a strong object. |
| 5247 if (is_strict(language_mode)) { | 5145 if (is_strict(language_mode)) { |
| 5248 if (object->map()->is_strong()) { | 5146 if (receiver->map()->is_strong()) { |
| 5249 THROW_NEW_ERROR( | 5147 THROW_NEW_ERROR( |
| 5250 it.isolate(), | 5148 isolate, NewTypeError(MessageTemplate::kStrongDeleteProperty, |
| 5251 NewTypeError(MessageTemplate::kStrongDeleteProperty, object, | 5149 receiver, it->GetName()), |
| 5252 name), | |
| 5253 Object); | 5150 Object); |
| 5254 } | 5151 } |
| 5255 THROW_NEW_ERROR(it.isolate(), | 5152 THROW_NEW_ERROR(isolate, |
| 5256 NewTypeError(MessageTemplate::kStrictDeleteProperty, | 5153 NewTypeError(MessageTemplate::kStrictDeleteProperty, |
| 5257 name, object), | 5154 it->GetName(), receiver), |
| 5258 Object); | 5155 Object); |
| 5259 } | 5156 } |
| 5260 return it.isolate()->factory()->false_value(); | 5157 return it->factory()->false_value(); |
| 5261 } | 5158 } |
| 5262 | 5159 |
| 5263 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 5160 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 5264 ? KEEP_INOBJECT_PROPERTIES | |
| 5265 : CLEAR_INOBJECT_PROPERTIES; | |
| 5266 Handle<JSObject> holder = it.GetHolder<JSObject>(); | |
| 5267 // TODO(verwaest): Remove this temporary compatibility hack when blink | 5161 // TODO(verwaest): Remove this temporary compatibility hack when blink |
| 5268 // tests are updated. | 5162 // tests are updated. |
| 5269 if (!holder.is_identical_to(object) && | 5163 if (!holder.is_identical_to(receiver) && |
| 5270 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { | 5164 !(receiver->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { |
| 5271 return it.isolate()->factory()->true_value(); | 5165 return it->factory()->true_value(); |
| 5272 } | 5166 } |
| 5273 | 5167 |
| 5274 NormalizeProperties(holder, mode, 0, "DeletingProperty"); | 5168 if (it->IsElement()) { |
| 5275 DeleteNormalizedProperty(holder, name); | 5169 ElementsAccessor* accessor = holder->GetElementsAccessor(); |
| 5276 ReoptimizeIfPrototype(holder); | 5170 accessor->Delete(holder, it->index(), language_mode); |
| 5171 } else { |
| 5172 PropertyNormalizationMode mode = holder->map()->is_prototype_map() |
| 5173 ? KEEP_INOBJECT_PROPERTIES |
| 5174 : CLEAR_INOBJECT_PROPERTIES; |
| 5175 |
| 5176 JSObject::NormalizeProperties(holder, mode, 0, "DeletingProperty"); |
| 5177 JSObject::DeleteNormalizedProperty(holder, it->name()); |
| 5178 JSObject::ReoptimizeIfPrototype(holder); |
| 5179 } |
| 5277 | 5180 |
| 5278 if (is_observed) { | 5181 if (is_observed) { |
| 5279 RETURN_ON_EXCEPTION( | 5182 RETURN_ON_EXCEPTION(isolate, |
| 5280 it.isolate(), | 5183 JSObject::EnqueueChangeRecord( |
| 5281 EnqueueChangeRecord(object, "delete", name, old_value), Object); | 5184 receiver, "delete", it->GetName(), old_value), |
| 5185 Object); |
| 5282 } | 5186 } |
| 5283 | 5187 |
| 5284 return it.isolate()->factory()->true_value(); | 5188 return it->factory()->true_value(); |
| 5285 } | 5189 } |
| 5286 } | 5190 } |
| 5287 } | 5191 } |
| 5288 | 5192 |
| 5289 return it.isolate()->factory()->true_value(); | 5193 return it->factory()->true_value(); |
| 5290 } | 5194 } |
| 5291 | 5195 |
| 5292 | 5196 |
| 5293 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, | 5197 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, |
| 5294 uint32_t index, | 5198 uint32_t index, |
| 5295 LanguageMode language_mode) { | 5199 LanguageMode language_mode) { |
| 5296 if (object->IsJSProxy()) { | 5200 LookupIterator it(object->GetIsolate(), object, index); |
| 5297 return JSProxy::DeleteElementWithHandler(Handle<JSProxy>::cast(object), | 5201 return DeleteProperty(&it, language_mode); |
| 5298 index, language_mode); | |
| 5299 } | |
| 5300 return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, | |
| 5301 language_mode); | |
| 5302 } | 5202 } |
| 5303 | 5203 |
| 5304 | 5204 |
| 5305 MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, | 5205 MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, |
| 5306 Handle<Name> name, | 5206 Handle<Name> name, |
| 5307 LanguageMode language_mode) { | 5207 LanguageMode language_mode) { |
| 5308 if (object->IsJSProxy()) { | 5208 uint32_t index; |
| 5309 return JSProxy::DeletePropertyWithHandler(Handle<JSProxy>::cast(object), | 5209 LookupIterator::Configuration c = LookupIterator::HIDDEN; |
| 5310 name, language_mode); | 5210 LookupIterator it = name->AsArrayIndex(&index) |
| 5311 } | 5211 ? LookupIterator(name->GetIsolate(), object, index, c) |
| 5312 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, | 5212 : LookupIterator(object, name, c); |
| 5313 language_mode); | 5213 return JSObject::DeleteProperty(&it, language_mode); |
| 5314 } | 5214 } |
| 5315 | 5215 |
| 5316 | 5216 |
| 5317 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 5217 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 5318 ElementsKind kind, | 5218 ElementsKind kind, |
| 5319 Object* object) { | 5219 Object* object) { |
| 5320 DCHECK(IsFastObjectElementsKind(kind) || | 5220 DCHECK(IsFastObjectElementsKind(kind) || |
| 5321 kind == DICTIONARY_ELEMENTS); | 5221 kind == DICTIONARY_ELEMENTS); |
| 5322 if (IsFastObjectElementsKind(kind)) { | 5222 if (IsFastObjectElementsKind(kind)) { |
| 5323 int length = IsJSArray() | 5223 int length = IsJSArray() |
| (...skipping 11747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17071 Handle<Object> new_value) { | 16971 Handle<Object> new_value) { |
| 17072 if (cell->value() != *new_value) { | 16972 if (cell->value() != *new_value) { |
| 17073 cell->set_value(*new_value); | 16973 cell->set_value(*new_value); |
| 17074 Isolate* isolate = cell->GetIsolate(); | 16974 Isolate* isolate = cell->GetIsolate(); |
| 17075 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16975 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17076 isolate, DependentCode::kPropertyCellChangedGroup); | 16976 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17077 } | 16977 } |
| 17078 } | 16978 } |
| 17079 } // namespace internal | 16979 } // namespace internal |
| 17080 } // namespace v8 | 16980 } // namespace v8 |
| OLD | NEW |