Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: src/objects.cc

Issue 468073002: Rewrite DeleteProperty using the LookupIterator (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/objects.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698