From 995ea2bd824c3b5f15222a3b6e839fd9e910668f Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Thu, 10 Oct 2013 15:27:02 +0000 Subject: [PATCH] Handlify JSObject::GetProperty????Interceptor. R=mstarzinger@chromium.org BUG= Review URL: https://codereview.chromium.org/25669004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17145 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 96 +++++++++++++++++++++++++++++------------------ src/objects.h | 20 +++++++--- src/runtime.cc | 5 ++- src/stub-cache.cc | 40 ++++++++++---------- 4 files changed, 96 insertions(+), 65 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index d8a6f13307..dc3ac255ea 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -142,6 +142,20 @@ void Object::Lookup(Name* name, LookupResult* result) { } +Handle Object::GetPropertyWithReceiver( + Handle object, + Handle receiver, + Handle name, + PropertyAttributes* attributes) { + LookupResult lookup(name->GetIsolate()); + object->Lookup(*name, &lookup); + Handle result = + GetProperty(object, receiver, &lookup, name, attributes); + ASSERT(*attributes <= ABSENT); + return result; +} + + MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, Name* name, PropertyAttributes* attributes) { @@ -803,6 +817,7 @@ MaybeObject* Object::GetPropertyOrFail(Handle object, } +// TODO(yangguo): handlify this and get rid of. MaybeObject* Object::GetProperty(Object* receiver, LookupResult* result, Name* name, @@ -881,9 +896,16 @@ MaybeObject* Object::GetProperty(Object* receiver, receiver, result->GetCallbackObject(), name); case HANDLER: return result->proxy()->GetPropertyWithHandler(receiver, name); - case INTERCEPTOR: - return result->holder()->GetPropertyWithInterceptor( - receiver, name, attributes); + case INTERCEPTOR: { + HandleScope scope(isolate); + Handle value = JSObject::GetPropertyWithInterceptor( + handle(result->holder(), isolate), + handle(receiver, isolate), + handle(name, isolate), + attributes); + RETURN_IF_EMPTY_HANDLE(isolate, value); + return *value; + } case TRANSITION: case NONEXISTENT: UNREACHABLE(); @@ -12951,21 +12973,26 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() { } -MaybeObject* JSObject::GetPropertyPostInterceptor( - Object* receiver, - Name* name, +Handle JSObject::GetPropertyPostInterceptor( + Handle object, + Handle receiver, + Handle name, PropertyAttributes* attributes) { // Check local property in holder, ignore interceptor. - LookupResult result(GetIsolate()); - LocalLookupRealNamedProperty(name, &result); - if (result.IsFound()) { - return GetProperty(receiver, &result, name, attributes); + Isolate* isolate = object->GetIsolate(); + LookupResult lookup(isolate); + object->LocalLookupRealNamedProperty(*name, &lookup); + Handle result; + if (lookup.IsFound()) { + result = GetProperty(object, receiver, &lookup, name, attributes); + } else { + // Continue searching via the prototype chain. + Handle prototype(object->GetPrototype(), isolate); + *attributes = ABSENT; + if (prototype->IsNull()) return isolate->factory()->undefined_value(); + result = GetPropertyWithReceiver(prototype, receiver, name, attributes); } - // Continue searching via the prototype chain. - Object* pt = GetPrototype(); - *attributes = ABSENT; - if (pt->IsNull()) return GetHeap()->undefined_value(); - return pt->GetPropertyWithReceiver(receiver, name, attributes); + return result; } @@ -12983,44 +13010,39 @@ MaybeObject* JSObject::GetLocalPropertyPostInterceptor( } -MaybeObject* JSObject::GetPropertyWithInterceptor( - Object* receiver, - Name* name, +Handle JSObject::GetPropertyWithInterceptor( + Handle object, + Handle receiver, + Handle name, PropertyAttributes* attributes) { - // TODO(rossberg): Support symbols in the API. - if (name->IsSymbol()) return GetHeap()->undefined_value(); + Isolate* isolate = object->GetIsolate(); - Isolate* isolate = GetIsolate(); - InterceptorInfo* interceptor = GetNamedInterceptor(); - HandleScope scope(isolate); - Handle receiver_handle(receiver, isolate); - Handle holder_handle(this); - Handle name_handle(String::cast(name)); + // TODO(rossberg): Support symbols in the API. + if (name->IsSymbol()) return isolate->factory()->undefined_value(); + + Handle interceptor(object->GetNamedInterceptor(), isolate); + Handle name_string = Handle::cast(name); if (!interceptor->getter()->IsUndefined()) { v8::NamedPropertyGetterCallback getter = v8::ToCData(interceptor->getter()); LOG(isolate, - ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); + ApiNamedPropertyAccess("interceptor-named-get", *object, *name)); PropertyCallbackArguments - args(isolate, interceptor->data(), receiver, this); + args(isolate, interceptor->data(), *receiver, *object); v8::Handle result = - args.Call(getter, v8::Utils::ToLocal(name_handle)); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); + args.Call(getter, v8::Utils::ToLocal(name_string)); + RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); if (!result.IsEmpty()) { *attributes = NONE; Handle result_internal = v8::Utils::OpenHandle(*result); result_internal->VerifyApiCallResultType(); - return *result_internal; + // Rebox handle to escape this scope. + return handle(*result_internal, isolate); } } - MaybeObject* result = holder_handle->GetPropertyPostInterceptor( - *receiver_handle, - *name_handle, - attributes); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); - return result; + return GetPropertyPostInterceptor(object, receiver, name, attributes); } diff --git a/src/objects.h b/src/objects.h index e0ab9841cb..5d3265bc78 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1457,6 +1457,12 @@ class Object : public MaybeObject { MUST_USE_RESULT inline MaybeObject* GetProperty( Name* key, PropertyAttributes* attributes); + + // TODO(yangguo): this should eventually replace the non-handlified version. + static Handle GetPropertyWithReceiver(Handle object, + Handle receiver, + Handle name, + PropertyAttributes* attributes); MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver( Object* receiver, Name* key, @@ -2243,13 +2249,15 @@ class JSObject: public JSReceiver { LookupResult* result, Name* name, PropertyAttributes* attributes); - MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor( - Object* receiver, - Name* name, + static Handle GetPropertyWithInterceptor( + Handle object, + Handle receiver, + Handle name, PropertyAttributes* attributes); - MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor( - Object* receiver, - Name* name, + static Handle GetPropertyPostInterceptor( + Handle object, + Handle receiver, + Handle name, PropertyAttributes* attributes); MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor( Object* receiver, diff --git a/src/runtime.cc b/src/runtime.cc index 26dc36d530..4ad9d616e8 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -10888,7 +10888,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) { CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); PropertyAttributes attributes; - return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); + Handle result = + JSObject::GetPropertyWithInterceptor(obj, obj, name, &attributes); + RETURN_IF_EMPTY_HANDLE(isolate, result); + return *result; } diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 4eb6241d87..f8e09c405d 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -1223,8 +1223,8 @@ static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) { } -static MaybeObject* LoadWithInterceptor(Arguments* args, - PropertyAttributes* attrs) { +static Handle LoadWithInterceptor(Arguments* args, + PropertyAttributes* attrs) { ASSERT(args->length() == StubCache::kInterceptorArgsLength); Handle name_handle = args->at(StubCache::kInterceptorArgsNameIndex); @@ -1238,9 +1238,10 @@ static MaybeObject* LoadWithInterceptor(Arguments* args, Isolate* isolate = receiver_handle->GetIsolate(); // TODO(rossberg): Support symbols in the API. - if (name_handle->IsSymbol()) - return holder_handle->GetPropertyPostInterceptor( - *receiver_handle, *name_handle, attrs); + if (name_handle->IsSymbol()) { + return JSObject::GetPropertyPostInterceptor( + holder_handle, receiver_handle, name_handle, attrs); + } Handle name = Handle::cast(name_handle); Address getter_address = v8::ToCData
(interceptor_info->getter()); @@ -1253,24 +1254,21 @@ static MaybeObject* LoadWithInterceptor(Arguments* args, *receiver_handle, *holder_handle); { - // Use the interceptor getter. HandleScope scope(isolate); + // Use the interceptor getter. v8::Handle r = callback_args.Call(getter, v8::Utils::ToLocal(name)); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); + RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); if (!r.IsEmpty()) { *attrs = NONE; Handle result = v8::Utils::OpenHandle(*r); result->VerifyApiCallResultType(); - return *result; + return scope.CloseAndEscape(result); } } - MaybeObject* result = holder_handle->GetPropertyPostInterceptor( - *receiver_handle, - *name_handle, - attrs); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); + Handle result = JSObject::GetPropertyPostInterceptor( + holder_handle, receiver_handle, name_handle, attrs); return result; } @@ -1281,25 +1279,25 @@ static MaybeObject* LoadWithInterceptor(Arguments* args, */ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) { PropertyAttributes attr = NONE; - Object* result; - { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr); - if (!maybe_result->ToObject(&result)) return maybe_result; - } + HandleScope scope(isolate); + Handle result = LoadWithInterceptor(&args, &attr); + RETURN_IF_EMPTY_HANDLE(isolate, result); // If the property is present, return it. - if (attr != ABSENT) return result; + if (attr != ABSENT) return *result; return ThrowReferenceError(isolate, Name::cast(args[0])); } RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) { PropertyAttributes attr; - MaybeObject* result = LoadWithInterceptor(&args, &attr); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); + HandleScope scope(isolate); + Handle result = LoadWithInterceptor(&args, &attr); + RETURN_IF_EMPTY_HANDLE(isolate, result); // This is call IC. In this case, we simply return the undefined result which // will lead to an exception when trying to invoke the result as a // function. - return result; + return *result; }