Chromium Code Reviews| 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 4837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4848 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, | 4848 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, |
| 4849 Handle<Object> value) { | 4849 Handle<Object> value) { |
| 4850 DCHECK(!object->IsJSGlobalProxy()); | 4850 DCHECK(!object->IsJSGlobalProxy()); |
| 4851 Isolate* isolate = object->GetIsolate(); | 4851 Isolate* isolate = object->GetIsolate(); |
| 4852 Handle<Name> name = isolate->factory()->hidden_string(); | 4852 Handle<Name> name = isolate->factory()->hidden_string(); |
| 4853 SetOwnPropertyIgnoreAttributes(object, name, value, DONT_ENUM); | 4853 SetOwnPropertyIgnoreAttributes(object, name, value, DONT_ENUM); |
| 4854 return object; | 4854 return object; |
| 4855 } | 4855 } |
| 4856 | 4856 |
| 4857 | 4857 |
| 4858 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, | 4858 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, |
|
Jakob Kummerow
2014/08/13 12:07:25
This seems to have become dead code now.
| |
| 4859 Handle<Name> name, | 4859 Handle<Name> name, |
| 4860 DeleteMode delete_mode) { | 4860 DeleteMode delete_mode) { |
| 4861 // Check own property, ignore interceptor. | 4861 // Check own property, ignore interceptor. |
| 4862 Isolate* isolate = object->GetIsolate(); | 4862 Isolate* isolate = object->GetIsolate(); |
| 4863 LookupResult lookup(isolate); | 4863 LookupResult lookup(isolate); |
| 4864 object->LookupOwnRealNamedProperty(name, &lookup); | 4864 object->LookupOwnRealNamedProperty(name, &lookup); |
| 4865 if (!lookup.IsFound()) return isolate->factory()->true_value(); | 4865 if (!lookup.IsFound()) return isolate->factory()->true_value(); |
| 4866 | 4866 |
| 4867 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 4867 PropertyNormalizationMode mode = object->map()->is_prototype_map() |
| 4868 ? KEEP_INOBJECT_PROPERTIES | 4868 ? KEEP_INOBJECT_PROPERTIES |
| 4869 : CLEAR_INOBJECT_PROPERTIES; | 4869 : CLEAR_INOBJECT_PROPERTIES; |
| 4870 // Normalize object if needed. | 4870 // Normalize object if needed. |
| 4871 NormalizeProperties(object, mode, 0); | 4871 NormalizeProperties(object, mode, 0); |
| 4872 | 4872 |
| 4873 Handle<Object> result = DeleteNormalizedProperty(object, name, delete_mode); | 4873 Handle<Object> result = DeleteNormalizedProperty(object, name, delete_mode); |
| 4874 ReoptimizeIfPrototype(object); | 4874 ReoptimizeIfPrototype(object); |
| 4875 return result; | 4875 return result; |
| 4876 } | 4876 } |
| 4877 | 4877 |
| 4878 | 4878 |
| 4879 MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor( | 4879 MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor( |
| 4880 Handle<JSObject> object, Handle<Name> name) { | 4880 Handle<JSObject> holder, Handle<JSObject> receiver, Handle<Name> name) { |
| 4881 Isolate* isolate = object->GetIsolate(); | 4881 Isolate* isolate = holder->GetIsolate(); |
| 4882 | 4882 |
| 4883 // TODO(rossberg): Support symbols in the API. | 4883 // TODO(rossberg): Support symbols in the API. |
| 4884 if (name->IsSymbol()) return isolate->factory()->false_value(); | 4884 if (name->IsSymbol()) return MaybeHandle<Object>(); |
| 4885 | 4885 |
| 4886 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | 4886 Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor()); |
| 4887 if (!interceptor->deleter()->IsUndefined()) { | 4887 if (interceptor->deleter()->IsUndefined()) return MaybeHandle<Object>(); |
| 4888 v8::NamedPropertyDeleterCallback deleter = | 4888 |
| 4889 v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter()); | 4889 v8::NamedPropertyDeleterCallback deleter = |
| 4890 LOG(isolate, | 4890 v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter()); |
| 4891 ApiNamedPropertyAccess("interceptor-named-delete", *object, *name)); | 4891 LOG(isolate, |
| 4892 PropertyCallbackArguments args( | 4892 ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name)); |
| 4893 isolate, interceptor->data(), *object, *object); | 4893 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 4894 v8::Handle<v8::Boolean> result = | 4894 *holder); |
| 4895 args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name))); | 4895 v8::Handle<v8::Boolean> result = |
| 4896 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 4896 args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name))); |
| 4897 if (!result.IsEmpty()) { | 4897 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 4898 DCHECK(result->IsBoolean()); | 4898 if (result.IsEmpty()) return MaybeHandle<Object>(); |
| 4899 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 4899 |
| 4900 result_internal->VerifyApiCallResultType(); | 4900 DCHECK(result->IsBoolean()); |
| 4901 // Rebox CustomArguments::kReturnValueOffset before returning. | 4901 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
| 4902 return handle(*result_internal, isolate); | 4902 result_internal->VerifyApiCallResultType(); |
| 4903 } | 4903 // Rebox CustomArguments::kReturnValueOffset before returning. |
| 4904 } | 4904 return handle(*result_internal, isolate); |
| 4905 Handle<Object> result = | |
| 4906 DeletePropertyPostInterceptor(object, name, NORMAL_DELETION); | |
| 4907 return result; | |
| 4908 } | 4905 } |
| 4909 | 4906 |
| 4910 | 4907 |
| 4911 MaybeHandle<Object> JSObject::DeleteElementWithInterceptor( | 4908 MaybeHandle<Object> JSObject::DeleteElementWithInterceptor( |
| 4912 Handle<JSObject> object, | 4909 Handle<JSObject> object, |
| 4913 uint32_t index) { | 4910 uint32_t index) { |
| 4914 Isolate* isolate = object->GetIsolate(); | 4911 Isolate* isolate = object->GetIsolate(); |
| 4915 Factory* factory = isolate->factory(); | 4912 Factory* factory = isolate->factory(); |
| 4916 | 4913 |
| 4917 // Make sure that the top context does not change when doing | 4914 // Make sure that the top context does not change when doing |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5013 } | 5010 } |
| 5014 } | 5011 } |
| 5015 | 5012 |
| 5016 return result; | 5013 return result; |
| 5017 } | 5014 } |
| 5018 | 5015 |
| 5019 | 5016 |
| 5020 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 5017 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
| 5021 Handle<Name> name, | 5018 Handle<Name> name, |
| 5022 DeleteMode delete_mode) { | 5019 DeleteMode delete_mode) { |
| 5023 Isolate* isolate = object->GetIsolate(); | |
| 5024 // ECMA-262, 3rd, 8.6.2.5 | 5020 // ECMA-262, 3rd, 8.6.2.5 |
| 5025 DCHECK(name->IsName()); | 5021 DCHECK(name->IsName()); |
| 5026 | 5022 |
| 5027 // Check access rights if needed. | |
| 5028 if (object->IsAccessCheckNeeded() && | |
| 5029 !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) { | |
| 5030 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); | |
| 5031 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | |
| 5032 return isolate->factory()->false_value(); | |
| 5033 } | |
| 5034 | |
| 5035 if (object->IsJSGlobalProxy()) { | |
| 5036 PrototypeIterator iter(isolate, object); | |
| 5037 if (iter.IsAtEnd()) return isolate->factory()->false_value(); | |
| 5038 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | |
| 5039 return JSGlobalObject::DeleteProperty( | |
| 5040 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)), name, | |
| 5041 delete_mode); | |
| 5042 } | |
| 5043 | |
| 5044 uint32_t index = 0; | 5023 uint32_t index = 0; |
| 5045 if (name->AsArrayIndex(&index)) { | 5024 if (name->AsArrayIndex(&index)) { |
| 5046 return DeleteElement(object, index, delete_mode); | 5025 return DeleteElement(object, index, delete_mode); |
| 5047 } | 5026 } |
| 5048 | 5027 |
| 5049 LookupResult lookup(isolate); | 5028 // Skip interceptors on FORCE_DELETION. |
| 5050 object->LookupOwn(name, &lookup, true); | 5029 LookupIterator::Configuration config = |
| 5051 if (!lookup.IsFound()) return isolate->factory()->true_value(); | 5030 delete_mode == FORCE_DELETION ? LookupIterator::CHECK_HIDDEN_ACCESS |
| 5052 // Ignore attributes if forcing a deletion. | 5031 : LookupIterator::CHECK_OWN; |
| 5053 if (lookup.IsDontDelete() && delete_mode != FORCE_DELETION) { | |
| 5054 if (delete_mode == STRICT_DELETION) { | |
| 5055 // Deleting a non-configurable property in strict mode. | |
| 5056 Handle<Object> args[2] = { name, object }; | |
| 5057 Handle<Object> error = isolate->factory()->NewTypeError( | |
| 5058 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); | |
| 5059 isolate->Throw(*error); | |
| 5060 return Handle<Object>(); | |
| 5061 } | |
| 5062 return isolate->factory()->false_value(); | |
| 5063 } | |
| 5064 | 5032 |
| 5065 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 5033 LookupIterator it(object, name, config); |
| 5034 | |
| 5066 bool is_observed = object->map()->is_observed() && | 5035 bool is_observed = object->map()->is_observed() && |
| 5067 *name != isolate->heap()->hidden_string(); | 5036 *name != it.isolate()->heap()->hidden_string(); |
| 5068 if (is_observed && lookup.IsDataProperty()) { | |
| 5069 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); | |
| 5070 } | |
| 5071 Handle<Object> result; | |
| 5072 | 5037 |
| 5073 // Check for interceptor. | 5038 for (; it.IsFound(); it.Next()) { |
| 5074 if (lookup.IsInterceptor()) { | 5039 switch (it.state()) { |
| 5075 // Skip interceptor if forcing a deletion. | 5040 case LookupIterator::NOT_FOUND: |
| 5076 if (delete_mode == FORCE_DELETION) { | 5041 case LookupIterator::JSPROXY: |
| 5077 result = DeletePropertyPostInterceptor(object, name, delete_mode); | 5042 UNREACHABLE(); |
| 5078 } else { | 5043 case LookupIterator::ACCESS_CHECK: |
| 5079 ASSIGN_RETURN_ON_EXCEPTION( | 5044 if (it.HasAccess(v8::ACCESS_DELETE)) break; |
| 5080 isolate, result, | 5045 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(), |
| 5081 DeletePropertyWithInterceptor(object, name), | 5046 v8::ACCESS_DELETE); |
| 5082 Object); | 5047 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); |
| 5083 } | 5048 return it.isolate()->factory()->false_value(); |
| 5084 } else { | 5049 case LookupIterator::INTERCEPTOR: { |
| 5085 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 5050 MaybeHandle<Object> maybe_result = |
| 5086 ? KEEP_INOBJECT_PROPERTIES | 5051 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(), |
| 5087 : CLEAR_INOBJECT_PROPERTIES; | 5052 object, it.name()); |
| 5088 // Normalize object if needed. | 5053 // Delete with interceptor succeeded. Return result. |
| 5089 NormalizeProperties(object, mode, 0); | 5054 if (!maybe_result.is_null()) return maybe_result; |
| 5090 // Make sure the properties are normalized before removing the entry. | 5055 // An exception was thrown in the interceptor. Propagate. |
| 5091 result = DeleteNormalizedProperty(object, name, delete_mode); | 5056 if (it.isolate()->has_pending_exception()) return maybe_result; |
| 5092 ReoptimizeIfPrototype(object); | 5057 break; |
| 5093 } | 5058 } |
| 5059 case LookupIterator::PROPERTY: { | |
| 5060 if (!it.HasProperty()) continue; | |
| 5061 if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) { | |
| 5062 // Fail if the property is not configurable. | |
| 5063 if (delete_mode == STRICT_DELETION) { | |
| 5064 Handle<Object> args[2] = {name, object}; | |
| 5065 Handle<Object> error = it.isolate()->factory()->NewTypeError( | |
| 5066 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); | |
| 5067 it.isolate()->Throw(*error); | |
| 5068 return Handle<Object>(); | |
| 5069 } | |
| 5070 return it.isolate()->factory()->false_value(); | |
| 5071 } | |
| 5094 | 5072 |
| 5095 if (is_observed) { | 5073 Handle<Object> old_value; |
| 5096 Maybe<bool> maybe = HasOwnProperty(object, name); | 5074 if (is_observed) { |
| 5097 if (!maybe.has_value) return MaybeHandle<Object>(); | 5075 switch (it.property_kind()) { |
| 5098 if (!maybe.value) { | 5076 case LookupIterator::ACCESSOR: |
| 5099 EnqueueChangeRecord(object, "delete", name, old_value); | 5077 old_value = it.isolate()->factory()->the_hole_value(); |
| 5078 break; | |
| 5079 case LookupIterator::DATA: | |
| 5080 old_value = it.GetDataValue(); | |
| 5081 } | |
| 5082 } | |
| 5083 | |
| 5084 PropertyNormalizationMode mode = object->map()->is_prototype_map() | |
| 5085 ? KEEP_INOBJECT_PROPERTIES | |
| 5086 : CLEAR_INOBJECT_PROPERTIES; | |
| 5087 Handle<JSObject> holder = it.GetHolder<JSObject>(); | |
| 5088 NormalizeProperties(holder, mode, 0); | |
| 5089 Handle<Object> result = | |
| 5090 DeleteNormalizedProperty(holder, name, delete_mode); | |
| 5091 ReoptimizeIfPrototype(holder); | |
| 5092 | |
| 5093 if (is_observed) { | |
| 5094 EnqueueChangeRecord(object, "delete", name, old_value); | |
| 5095 } | |
| 5096 | |
| 5097 return result; | |
| 5098 } | |
| 5100 } | 5099 } |
| 5101 } | 5100 } |
| 5102 | 5101 |
| 5103 return result; | 5102 return it.isolate()->factory()->true_value(); |
| 5104 } | 5103 } |
| 5105 | 5104 |
| 5106 | 5105 |
| 5107 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, | 5106 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, |
| 5108 uint32_t index, | 5107 uint32_t index, |
| 5109 DeleteMode mode) { | 5108 DeleteMode mode) { |
| 5110 if (object->IsJSProxy()) { | 5109 if (object->IsJSProxy()) { |
| 5111 return JSProxy::DeleteElementWithHandler( | 5110 return JSProxy::DeleteElementWithHandler( |
| 5112 Handle<JSProxy>::cast(object), index, mode); | 5111 Handle<JSProxy>::cast(object), index, mode); |
| 5113 } | 5112 } |
| (...skipping 11565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16679 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16678 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16680 static const char* error_messages_[] = { | 16679 static const char* error_messages_[] = { |
| 16681 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16680 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16682 }; | 16681 }; |
| 16683 #undef ERROR_MESSAGES_TEXTS | 16682 #undef ERROR_MESSAGES_TEXTS |
| 16684 return error_messages_[reason]; | 16683 return error_messages_[reason]; |
| 16685 } | 16684 } |
| 16686 | 16685 |
| 16687 | 16686 |
| 16688 } } // namespace v8::internal | 16687 } } // namespace v8::internal |
| OLD | NEW |