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

Side by Side Diff: src/objects.cc

Issue 23766003: Handlify JSObject::DeleteElement method. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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
« no previous file with comments | « 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 // 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 5012 matching lines...) Expand 10 before | Expand all | Expand 10 after
5023 return handle(*result_internal, isolate); 5023 return handle(*result_internal, isolate);
5024 } 5024 }
5025 } 5025 }
5026 Handle<Object> result = 5026 Handle<Object> result =
5027 DeletePropertyPostInterceptor(object, name, NORMAL_DELETION); 5027 DeletePropertyPostInterceptor(object, name, NORMAL_DELETION);
5028 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 5028 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5029 return result; 5029 return result;
5030 } 5030 }
5031 5031
5032 5032
5033 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { 5033 // TODO(mstarzinger): Temporary wrapper until handlified.
5034 Isolate* isolate = GetIsolate(); 5034 static Handle<Object> AccessorDelete(Handle<JSObject> object,
5035 Heap* heap = isolate->heap(); 5035 uint32_t index,
5036 HandleScope scope(isolate); 5036 JSObject::DeleteMode mode) {
5037 CALL_HEAP_FUNCTION(object->GetIsolate(),
5038 object->GetElementsAccessor()->Delete(*object,
5039 index,
5040 mode),
5041 Object);
5042 }
5043
5044
5045 Handle<Object> JSObject::DeleteElementWithInterceptor(Handle<JSObject> object,
5046 uint32_t index) {
5047 Isolate* isolate = object->GetIsolate();
5048 Factory* factory = isolate->factory();
5037 5049
5038 // Make sure that the top context does not change when doing 5050 // Make sure that the top context does not change when doing
5039 // callbacks or interceptor calls. 5051 // callbacks or interceptor calls.
5040 AssertNoContextChange ncc; 5052 AssertNoContextChange ncc;
5041 5053
5042 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 5054 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
5043 if (interceptor->deleter()->IsUndefined()) return heap->false_value(); 5055 if (interceptor->deleter()->IsUndefined()) return factory->false_value();
5044 v8::IndexedPropertyDeleterCallback deleter = 5056 v8::IndexedPropertyDeleterCallback deleter =
5045 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); 5057 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
5046 Handle<JSObject> this_handle(this);
5047 LOG(isolate, 5058 LOG(isolate,
5048 ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); 5059 ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index));
5049 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); 5060 PropertyCallbackArguments args(
5061 isolate, interceptor->data(), *object, *object);
5050 v8::Handle<v8::Boolean> result = args.Call(deleter, index); 5062 v8::Handle<v8::Boolean> result = args.Call(deleter, index);
5051 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 5063 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5052 if (!result.IsEmpty()) { 5064 if (!result.IsEmpty()) {
5053 ASSERT(result->IsBoolean()); 5065 ASSERT(result->IsBoolean());
5054 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 5066 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
5055 result_internal->VerifyApiCallResultType(); 5067 result_internal->VerifyApiCallResultType();
5056 return *result_internal; 5068 // Rebox CustomArguments::kReturnValueOffset before returning.
5069 return handle(*result_internal, isolate);
5057 } 5070 }
5058 MaybeObject* raw_result = this_handle->GetElementsAccessor()->Delete( 5071 Handle<Object> delete_result = AccessorDelete(object, index, NORMAL_DELETION);
5059 *this_handle, 5072 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5060 index, 5073 return delete_result;
5061 NORMAL_DELETION);
5062 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5063 return raw_result;
5064 } 5074 }
5065 5075
5066 5076
5067 Handle<Object> JSObject::DeleteElement(Handle<JSObject> obj, 5077 Handle<Object> JSObject::DeleteElement(Handle<JSObject> object,
5068 uint32_t index, 5078 uint32_t index,
5069 DeleteMode mode) { 5079 DeleteMode mode) {
5070 CALL_HEAP_FUNCTION(obj->GetIsolate(), 5080 Isolate* isolate = object->GetIsolate();
5071 obj->DeleteElement(index, mode), 5081 Factory* factory = isolate->factory();
5072 Object); 5082
5083 // Check access rights if needed.
5084 if (object->IsAccessCheckNeeded() &&
5085 !isolate->MayIndexedAccess(*object, index, v8::ACCESS_DELETE)) {
5086 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_DELETE);
5087 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5088 return factory->false_value();
5089 }
5090
5091 if (object->IsStringObjectWithCharacterAt(index)) {
5092 if (mode == STRICT_DELETION) {
5093 // Deleting a non-configurable property in strict mode.
5094 Handle<Object> name = factory->NewNumberFromUint(index);
5095 Handle<Object> args[2] = { name, object };
5096 Handle<Object> error =
5097 factory->NewTypeError("strict_delete_property",
5098 HandleVector(args, 2));
5099 isolate->Throw(*error);
5100 return Handle<Object>();
5101 }
5102 return factory->false_value();
5103 }
5104
5105 if (object->IsJSGlobalProxy()) {
5106 Handle<Object> proto(object->GetPrototype(), isolate);
5107 if (proto->IsNull()) return factory->false_value();
5108 ASSERT(proto->IsJSGlobalObject());
5109 return DeleteElement(Handle<JSObject>::cast(proto), index, mode);
5110 }
5111
5112 Handle<Object> old_value;
5113 bool should_enqueue_change_record = false;
5114 if (FLAG_harmony_observation && object->map()->is_observed()) {
5115 should_enqueue_change_record = object->HasLocalElement(index);
5116 if (should_enqueue_change_record) {
5117 old_value = object->GetLocalElementAccessorPair(index) != NULL
5118 ? Handle<Object>::cast(factory->the_hole_value())
5119 : Object::GetElement(object, index);
5120 }
5121 }
5122
5123 // Skip interceptor if forcing deletion.
5124 Handle<Object> result;
5125 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) {
5126 result = DeleteElementWithInterceptor(object, index);
5127 } else {
5128 result = AccessorDelete(object, index, mode);
5129 }
5130
5131 if (should_enqueue_change_record && !object->HasLocalElement(index)) {
5132 Handle<String> name = factory->Uint32ToString(index);
5133 EnqueueChangeRecord(object, "deleted", name, old_value);
5134 }
5135
5136 return result;
5073 } 5137 }
5074 5138
5075 5139
5076 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
5077 Isolate* isolate = GetIsolate();
5078 // Check access rights if needed.
5079 if (IsAccessCheckNeeded() &&
5080 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) {
5081 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
5082 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5083 return isolate->heap()->false_value();
5084 }
5085
5086 if (IsStringObjectWithCharacterAt(index)) {
5087 if (mode == STRICT_DELETION) {
5088 // Deleting a non-configurable property in strict mode.
5089 HandleScope scope(isolate);
5090 Handle<Object> holder(this, isolate);
5091 Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
5092 Handle<Object> args[2] = { name, holder };
5093 Handle<Object> error =
5094 isolate->factory()->NewTypeError("strict_delete_property",
5095 HandleVector(args, 2));
5096 return isolate->Throw(*error);
5097 }
5098 return isolate->heap()->false_value();
5099 }
5100
5101 if (IsJSGlobalProxy()) {
5102 Object* proto = GetPrototype();
5103 if (proto->IsNull()) return isolate->heap()->false_value();
5104 ASSERT(proto->IsJSGlobalObject());
5105 return JSGlobalObject::cast(proto)->DeleteElement(index, mode);
5106 }
5107
5108 // From this point on everything needs to be handlified.
5109 HandleScope scope(isolate);
5110 Handle<JSObject> self(this);
5111
5112 Handle<Object> old_value;
5113 bool should_enqueue_change_record = false;
5114 if (FLAG_harmony_observation && self->map()->is_observed()) {
5115 should_enqueue_change_record = self->HasLocalElement(index);
5116 if (should_enqueue_change_record) {
5117 old_value = self->GetLocalElementAccessorPair(index) != NULL
5118 ? Handle<Object>::cast(isolate->factory()->the_hole_value())
5119 : Object::GetElement(self, index);
5120 }
5121 }
5122
5123 MaybeObject* result;
5124 // Skip interceptor if forcing deletion.
5125 if (self->HasIndexedInterceptor() && mode != FORCE_DELETION) {
5126 result = self->DeleteElementWithInterceptor(index);
5127 } else {
5128 result = self->GetElementsAccessor()->Delete(*self, index, mode);
5129 }
5130
5131 Handle<Object> hresult;
5132 if (!result->ToHandle(&hresult, isolate)) return result;
5133
5134 if (should_enqueue_change_record && !self->HasLocalElement(index)) {
5135 Handle<String> name = isolate->factory()->Uint32ToString(index);
5136 EnqueueChangeRecord(self, "deleted", name, old_value);
5137 }
5138
5139 return *hresult;
5140 }
5141
5142
5143 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object, 5140 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
5144 Handle<Name> name, 5141 Handle<Name> name,
5145 DeleteMode mode) { 5142 DeleteMode mode) {
5146 Isolate* isolate = object->GetIsolate(); 5143 Isolate* isolate = object->GetIsolate();
5147 // ECMA-262, 3rd, 8.6.2.5 5144 // ECMA-262, 3rd, 8.6.2.5
5148 ASSERT(name->IsName()); 5145 ASSERT(name->IsName());
5149 5146
5150 // Check access rights if needed. 5147 // Check access rights if needed.
5151 if (object->IsAccessCheckNeeded() && 5148 if (object->IsAccessCheckNeeded() &&
5152 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_DELETE)) { 5149 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_DELETE)) {
(...skipping 10841 matching lines...) Expand 10 before | Expand all | Expand 10 after
15994 #define ERROR_MESSAGES_TEXTS(C, T) T, 15991 #define ERROR_MESSAGES_TEXTS(C, T) T,
15995 static const char* error_messages_[] = { 15992 static const char* error_messages_[] = {
15996 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 15993 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
15997 }; 15994 };
15998 #undef ERROR_MESSAGES_TEXTS 15995 #undef ERROR_MESSAGES_TEXTS
15999 return error_messages_[reason]; 15996 return error_messages_[reason];
16000 } 15997 }
16001 15998
16002 15999
16003 } } // namespace v8::internal 16000 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698