From 4ca46f3c3f773c1ca119b885b4b86d8cd019252c Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Tue, 25 Mar 2014 10:15:12 +0000 Subject: [PATCH] Handlify GetElementWithReceiver and GetElementWithInterceptor. R=ishell@chromium.org Review URL: https://codereview.chromium.org/210763003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20230 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/builtins.cc | 23 +++---------- src/objects-inl.h | 14 ++------ src/objects.cc | 96 ++++++++++++++++++++++++++++--------------------------- src/objects.h | 13 +++++--- src/runtime.cc | 5 +-- src/stub-cache.cc | 8 +++-- 6 files changed, 72 insertions(+), 87 deletions(-) diff --git a/src/builtins.cc b/src/builtins.cc index b73ed6b..7603039 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -506,23 +506,7 @@ static bool ElementsAccessorHasElementWrapper( uint32_t key, Handle backing_store = Handle::null()) { return accessor->HasElement(*receiver, *holder, key, - backing_store.is_null() ? *backing_store : NULL); -} - - -// TODO(ishell): Temporary wrapper until handlified. -static Handle ElementsAccessorGetWrapper( - Isolate* isolate, - ElementsAccessor* accessor, - Handle receiver, - Handle holder, - uint32_t key, - Handle backing_store = Handle::null()) { - CALL_HEAP_FUNCTION(isolate, - accessor->Get(*receiver, *holder, key, - backing_store.is_null() - ? *backing_store : NULL), - Object); + backing_store.is_null() ? NULL : *backing_store); } @@ -544,8 +528,8 @@ BUILTIN(ArrayPop) { Handle element; if (ElementsAccessorHasElementWrapper( accessor, array, array, new_length, elms_obj)) { - element = ElementsAccessorGetWrapper( - isolate, accessor, array, array, new_length, elms_obj); + element = accessor->Get( + array, array, new_length, elms_obj); } else { Handle proto(array->GetPrototype(), isolate); element = Object::GetElement(isolate, proto, len - 1); @@ -578,6 +562,7 @@ BUILTIN(ArrayShift) { // Get first element ElementsAccessor* accessor = array->GetElementsAccessor(); Handle first = accessor->Get(receiver, array, 0, elms_obj); + RETURN_IF_EMPTY_HANDLE(isolate, first); if (first->IsTheHole()) { first = isolate->factory()->undefined_value(); } diff --git a/src/objects-inl.h b/src/objects-inl.h index e454e2e..c358ee6 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1064,25 +1064,15 @@ Handle Object::GetElement(Isolate* isolate, // This was not always the case. This ASSERT is here to catch // leftover incorrect uses. ASSERT(AllowHeapAllocation::IsAllowed()); - CALL_HEAP_FUNCTION(isolate, - object->GetElementWithReceiver(isolate, *object, index), - Object); + return Object::GetElementWithReceiver(isolate, object, object, index); } -static Handle GetElementNoExceptionThrownHelper(Isolate* isolate, - Handle object, - uint32_t index) { - CALL_HEAP_FUNCTION(isolate, - object->GetElementWithReceiver(isolate, *object, index), - Object); -} - Handle Object::GetElementNoExceptionThrown(Isolate* isolate, Handle object, uint32_t index) { Handle result = - GetElementNoExceptionThrownHelper(isolate, object, index); + Object::GetElementWithReceiver(isolate, object, object, index); CHECK_NOT_EMPTY_HANDLE(isolate, result); return result; } diff --git a/src/objects.cc b/src/objects.cc index 131d031..11f53b9 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -962,63 +962,70 @@ MaybeObject* Object::GetProperty(Object* receiver, } -MaybeObject* Object::GetElementWithReceiver(Isolate* isolate, - Object* receiver, - uint32_t index) { - Heap* heap = isolate->heap(); - Object* holder = this; +Handle Object::GetElementWithReceiver(Isolate* isolate, + Handle object, + Handle receiver, + uint32_t index) { + Handle holder; // Iterate up the prototype chain until an element is found or the null // prototype is encountered. - for (holder = this; - holder != heap->null_value(); - holder = holder->GetPrototype(isolate)) { + for (holder = object; + !holder->IsNull(); + holder = Handle(holder->GetPrototype(isolate), isolate)) { if (!holder->IsJSObject()) { Context* native_context = isolate->context()->native_context(); if (holder->IsNumber()) { - holder = native_context->number_function()->instance_prototype(); + holder = Handle( + native_context->number_function()->instance_prototype(), isolate); } else if (holder->IsString()) { - holder = native_context->string_function()->instance_prototype(); + holder = Handle( + native_context->string_function()->instance_prototype(), isolate); } else if (holder->IsSymbol()) { - holder = native_context->symbol_function()->instance_prototype(); + holder = Handle( + native_context->symbol_function()->instance_prototype(), isolate); } else if (holder->IsBoolean()) { - holder = native_context->boolean_function()->instance_prototype(); + holder = Handle( + native_context->boolean_function()->instance_prototype(), isolate); } else if (holder->IsJSProxy()) { - return JSProxy::cast(holder)->GetElementWithHandler(receiver, index); + CALL_HEAP_FUNCTION(isolate, + Handle::cast(holder)->GetElementWithHandler( + *receiver, index), + Object); } else { // Undefined and null have no indexed properties. ASSERT(holder->IsUndefined() || holder->IsNull()); - return heap->undefined_value(); + return isolate->factory()->undefined_value(); } } // Inline the case for JSObjects. Doing so significantly improves the // performance of fetching elements where checking the prototype chain is // necessary. - JSObject* js_object = JSObject::cast(holder); + Handle js_object = Handle::cast(holder); // Check access rights if needed. if (js_object->IsAccessCheckNeeded()) { - Isolate* isolate = heap->isolate(); - if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) { - isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); - return heap->undefined_value(); + if (!isolate->MayIndexedAccessWrapper(js_object, index, v8::ACCESS_GET)) { + isolate->ReportFailedAccessCheckWrapper(js_object, v8::ACCESS_GET); + RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); + return isolate->factory()->undefined_value(); } } if (js_object->HasIndexedInterceptor()) { - return js_object->GetElementWithInterceptor(receiver, index); + return JSObject::GetElementWithInterceptor(js_object, receiver, index); } - if (js_object->elements() != heap->empty_fixed_array()) { - MaybeObject* result = js_object->GetElementsAccessor()->Get( + if (js_object->elements() != isolate->heap()->empty_fixed_array()) { + Handle result = js_object->GetElementsAccessor()->Get( receiver, js_object, index); - if (result != heap->the_hole_value()) return result; + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle()); + if (!result->IsTheHole()) return result; } } - return heap->undefined_value(); + return isolate->factory()->undefined_value(); } @@ -12922,46 +12929,41 @@ MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, } -MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, - uint32_t index) { - Isolate* isolate = GetIsolate(); - HandleScope scope(isolate); +Handle JSObject::GetElementWithInterceptor(Handle object, + Handle receiver, + uint32_t index) { + Isolate* isolate = object->GetIsolate(); // Make sure that the top context does not change when doing // callbacks or interceptor calls. AssertNoContextChange ncc(isolate); - Handle interceptor(GetIndexedInterceptor(), isolate); - Handle this_handle(receiver, isolate); - Handle holder_handle(this, isolate); + Handle interceptor(object->GetIndexedInterceptor(), isolate); if (!interceptor->getter()->IsUndefined()) { v8::IndexedPropertyGetterCallback getter = v8::ToCData(interceptor->getter()); LOG(isolate, - ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); + ApiIndexedPropertyAccess("interceptor-indexed-get", *object, index)); PropertyCallbackArguments - args(isolate, interceptor->data(), receiver, this); + args(isolate, interceptor->data(), *receiver, *object); v8::Handle result = args.Call(getter, index); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); + RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); if (!result.IsEmpty()) { Handle result_internal = v8::Utils::OpenHandle(*result); result_internal->VerifyApiCallResultType(); - return *result_internal; + // Rebox handle before return. + return Handle(*result_internal, isolate); } } - Heap* heap = holder_handle->GetHeap(); - ElementsAccessor* handler = holder_handle->GetElementsAccessor(); - MaybeObject* raw_result = handler->Get(*this_handle, - *holder_handle, - index); - if (raw_result != heap->the_hole_value()) return raw_result; - - RETURN_IF_SCHEDULED_EXCEPTION(isolate); + ElementsAccessor* handler = object->GetElementsAccessor(); + Handle result = handler->Get(receiver, object, index); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle()); + if (!result->IsTheHole()) return result; - Object* pt = holder_handle->GetPrototype(); - if (pt == heap->null_value()) return heap->undefined_value(); - return pt->GetElementWithReceiver(isolate, *this_handle, index); + Handle proto(object->GetPrototype(), isolate); + if (proto->IsNull()) return isolate->factory()->undefined_value(); + return Object::GetElementWithReceiver(isolate, proto, receiver, index); } diff --git a/src/objects.h b/src/objects.h index bb0f0f1..762892c 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1589,9 +1589,11 @@ class Object : public MaybeObject { Isolate* isolate, Handle object, uint32_t index); - MUST_USE_RESULT MaybeObject* GetElementWithReceiver(Isolate* isolate, - Object* receiver, - uint32_t index); + + static Handle GetElementWithReceiver(Isolate* isolate, + Handle object, + Handle receiver, + uint32_t index); // Return the object's prototype (might be Heap::null_value()). Object* GetPrototype(Isolate* isolate); @@ -2480,8 +2482,9 @@ class JSObject: public JSReceiver { // Returns the index'th element. // The undefined object if index is out of bounds. - MUST_USE_RESULT MaybeObject* GetElementWithInterceptor(Object* receiver, - uint32_t index); + static Handle GetElementWithInterceptor(Handle object, + Handle receiver, + uint32_t index); enum SetFastElementsCapacitySmiMode { kAllowSmiElements, diff --git a/src/runtime.cc b/src/runtime.cc index 4309dbd..1caaff0 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -11033,8 +11033,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) { CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); RUNTIME_ASSERT(obj->HasIndexedInterceptor()); CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); - - return obj->GetElementWithInterceptor(*obj, index); + Handle result = JSObject::GetElementWithInterceptor(obj, obj, index); + RETURN_IF_EMPTY_HANDLE(isolate, result); + return *result; } diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 092eaa3..ff641dd 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -664,10 +664,14 @@ RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { - JSObject* receiver = JSObject::cast(args[0]); + HandleScope scope(isolate); + Handle receiver = args.at(0); ASSERT(args.smi_at(1) >= 0); uint32_t index = args.smi_at(1); - return receiver->GetElementWithInterceptor(receiver, index); + Handle result = + JSObject::GetElementWithInterceptor(receiver, receiver, index); + RETURN_IF_EMPTY_HANDLE(isolate, result); + return *result; } -- 2.7.4