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
This commit is contained in:
yangguo@chromium.org 2013-10-10 15:27:02 +00:00
parent caeb19fa28
commit 995ea2bd82
4 changed files with 96 additions and 65 deletions

View File

@ -142,6 +142,20 @@ void Object::Lookup(Name* name, LookupResult* result) {
} }
Handle<Object> Object::GetPropertyWithReceiver(
Handle<Object> object,
Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes) {
LookupResult lookup(name->GetIsolate());
object->Lookup(*name, &lookup);
Handle<Object> result =
GetProperty(object, receiver, &lookup, name, attributes);
ASSERT(*attributes <= ABSENT);
return result;
}
MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
Name* name, Name* name,
PropertyAttributes* attributes) { PropertyAttributes* attributes) {
@ -803,6 +817,7 @@ MaybeObject* Object::GetPropertyOrFail(Handle<Object> object,
} }
// TODO(yangguo): handlify this and get rid of.
MaybeObject* Object::GetProperty(Object* receiver, MaybeObject* Object::GetProperty(Object* receiver,
LookupResult* result, LookupResult* result,
Name* name, Name* name,
@ -881,9 +896,16 @@ MaybeObject* Object::GetProperty(Object* receiver,
receiver, result->GetCallbackObject(), name); receiver, result->GetCallbackObject(), name);
case HANDLER: case HANDLER:
return result->proxy()->GetPropertyWithHandler(receiver, name); return result->proxy()->GetPropertyWithHandler(receiver, name);
case INTERCEPTOR: case INTERCEPTOR: {
return result->holder()->GetPropertyWithInterceptor( HandleScope scope(isolate);
receiver, name, attributes); Handle<Object> 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 TRANSITION:
case NONEXISTENT: case NONEXISTENT:
UNREACHABLE(); UNREACHABLE();
@ -12951,21 +12973,26 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() {
} }
MaybeObject* JSObject::GetPropertyPostInterceptor( Handle<Object> JSObject::GetPropertyPostInterceptor(
Object* receiver, Handle<JSObject> object,
Name* name, Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes) { PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor. // Check local property in holder, ignore interceptor.
LookupResult result(GetIsolate()); Isolate* isolate = object->GetIsolate();
LocalLookupRealNamedProperty(name, &result); LookupResult lookup(isolate);
if (result.IsFound()) { object->LocalLookupRealNamedProperty(*name, &lookup);
return GetProperty(receiver, &result, name, attributes); Handle<Object> result;
} if (lookup.IsFound()) {
result = GetProperty(object, receiver, &lookup, name, attributes);
} else {
// Continue searching via the prototype chain. // Continue searching via the prototype chain.
Object* pt = GetPrototype(); Handle<Object> prototype(object->GetPrototype(), isolate);
*attributes = ABSENT; *attributes = ABSENT;
if (pt->IsNull()) return GetHeap()->undefined_value(); if (prototype->IsNull()) return isolate->factory()->undefined_value();
return pt->GetPropertyWithReceiver(receiver, name, attributes); result = GetPropertyWithReceiver(prototype, receiver, name, attributes);
}
return result;
} }
@ -12983,44 +13010,39 @@ MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
} }
MaybeObject* JSObject::GetPropertyWithInterceptor( Handle<Object> JSObject::GetPropertyWithInterceptor(
Object* receiver, Handle<JSObject> object,
Name* name, Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes) { PropertyAttributes* attributes) {
// TODO(rossberg): Support symbols in the API. Isolate* isolate = object->GetIsolate();
if (name->IsSymbol()) return GetHeap()->undefined_value();
Isolate* isolate = GetIsolate(); // TODO(rossberg): Support symbols in the API.
InterceptorInfo* interceptor = GetNamedInterceptor(); if (name->IsSymbol()) return isolate->factory()->undefined_value();
HandleScope scope(isolate);
Handle<Object> receiver_handle(receiver, isolate); Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor(), isolate);
Handle<JSObject> holder_handle(this); Handle<String> name_string = Handle<String>::cast(name);
Handle<String> name_handle(String::cast(name));
if (!interceptor->getter()->IsUndefined()) { if (!interceptor->getter()->IsUndefined()) {
v8::NamedPropertyGetterCallback getter = v8::NamedPropertyGetterCallback getter =
v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
LOG(isolate, LOG(isolate,
ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); ApiNamedPropertyAccess("interceptor-named-get", *object, *name));
PropertyCallbackArguments PropertyCallbackArguments
args(isolate, interceptor->data(), receiver, this); args(isolate, interceptor->data(), *receiver, *object);
v8::Handle<v8::Value> result = v8::Handle<v8::Value> result =
args.Call(getter, v8::Utils::ToLocal(name_handle)); args.Call(getter, v8::Utils::ToLocal(name_string));
RETURN_IF_SCHEDULED_EXCEPTION(isolate); RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) { if (!result.IsEmpty()) {
*attributes = NONE; *attributes = NONE;
Handle<Object> result_internal = v8::Utils::OpenHandle(*result); Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType(); result_internal->VerifyApiCallResultType();
return *result_internal; // Rebox handle to escape this scope.
return handle(*result_internal, isolate);
} }
} }
MaybeObject* result = holder_handle->GetPropertyPostInterceptor( return GetPropertyPostInterceptor(object, receiver, name, attributes);
*receiver_handle,
*name_handle,
attributes);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result;
} }

View File

@ -1457,6 +1457,12 @@ class Object : public MaybeObject {
MUST_USE_RESULT inline MaybeObject* GetProperty( MUST_USE_RESULT inline MaybeObject* GetProperty(
Name* key, Name* key,
PropertyAttributes* attributes); PropertyAttributes* attributes);
// TODO(yangguo): this should eventually replace the non-handlified version.
static Handle<Object> GetPropertyWithReceiver(Handle<Object> object,
Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver( MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver(
Object* receiver, Object* receiver,
Name* key, Name* key,
@ -2243,13 +2249,15 @@ class JSObject: public JSReceiver {
LookupResult* result, LookupResult* result,
Name* name, Name* name,
PropertyAttributes* attributes); PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor( static Handle<Object> GetPropertyWithInterceptor(
Object* receiver, Handle<JSObject> object,
Name* name, Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes); PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor( static Handle<Object> GetPropertyPostInterceptor(
Object* receiver, Handle<JSObject> object,
Name* name, Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes); PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor( MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
Object* receiver, Object* receiver,

View File

@ -10888,7 +10888,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
PropertyAttributes attributes; PropertyAttributes attributes;
return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); Handle<Object> result =
JSObject::GetPropertyWithInterceptor(obj, obj, name, &attributes);
RETURN_IF_EMPTY_HANDLE(isolate, result);
return *result;
} }

View File

@ -1223,7 +1223,7 @@ static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) {
} }
static MaybeObject* LoadWithInterceptor(Arguments* args, static Handle<Object> LoadWithInterceptor(Arguments* args,
PropertyAttributes* attrs) { PropertyAttributes* attrs) {
ASSERT(args->length() == StubCache::kInterceptorArgsLength); ASSERT(args->length() == StubCache::kInterceptorArgsLength);
Handle<Name> name_handle = Handle<Name> name_handle =
@ -1238,9 +1238,10 @@ static MaybeObject* LoadWithInterceptor(Arguments* args,
Isolate* isolate = receiver_handle->GetIsolate(); Isolate* isolate = receiver_handle->GetIsolate();
// TODO(rossberg): Support symbols in the API. // TODO(rossberg): Support symbols in the API.
if (name_handle->IsSymbol()) if (name_handle->IsSymbol()) {
return holder_handle->GetPropertyPostInterceptor( return JSObject::GetPropertyPostInterceptor(
*receiver_handle, *name_handle, attrs); holder_handle, receiver_handle, name_handle, attrs);
}
Handle<String> name = Handle<String>::cast(name_handle); Handle<String> name = Handle<String>::cast(name_handle);
Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
@ -1253,24 +1254,21 @@ static MaybeObject* LoadWithInterceptor(Arguments* args,
*receiver_handle, *receiver_handle,
*holder_handle); *holder_handle);
{ {
// Use the interceptor getter.
HandleScope scope(isolate); HandleScope scope(isolate);
// Use the interceptor getter.
v8::Handle<v8::Value> r = v8::Handle<v8::Value> r =
callback_args.Call(getter, v8::Utils::ToLocal(name)); callback_args.Call(getter, v8::Utils::ToLocal(name));
RETURN_IF_SCHEDULED_EXCEPTION(isolate); RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!r.IsEmpty()) { if (!r.IsEmpty()) {
*attrs = NONE; *attrs = NONE;
Handle<Object> result = v8::Utils::OpenHandle(*r); Handle<Object> result = v8::Utils::OpenHandle(*r);
result->VerifyApiCallResultType(); result->VerifyApiCallResultType();
return *result; return scope.CloseAndEscape(result);
} }
} }
MaybeObject* result = holder_handle->GetPropertyPostInterceptor( Handle<Object> result = JSObject::GetPropertyPostInterceptor(
*receiver_handle, holder_handle, receiver_handle, name_handle, attrs);
*name_handle,
attrs);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result; return result;
} }
@ -1281,25 +1279,25 @@ static MaybeObject* LoadWithInterceptor(Arguments* args,
*/ */
RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) { RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) {
PropertyAttributes attr = NONE; PropertyAttributes attr = NONE;
Object* result; HandleScope scope(isolate);
{ MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr); Handle<Object> result = LoadWithInterceptor(&args, &attr);
if (!maybe_result->ToObject(&result)) return maybe_result; RETURN_IF_EMPTY_HANDLE(isolate, result);
}
// If the property is present, return it. // If the property is present, return it.
if (attr != ABSENT) return result; if (attr != ABSENT) return *result;
return ThrowReferenceError(isolate, Name::cast(args[0])); return ThrowReferenceError(isolate, Name::cast(args[0]));
} }
RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) { RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
PropertyAttributes attr; PropertyAttributes attr;
MaybeObject* result = LoadWithInterceptor(&args, &attr); HandleScope scope(isolate);
RETURN_IF_SCHEDULED_EXCEPTION(isolate); Handle<Object> result = LoadWithInterceptor(&args, &attr);
RETURN_IF_EMPTY_HANDLE(isolate, result);
// This is call IC. In this case, we simply return the undefined result which // 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 // will lead to an exception when trying to invoke the result as a
// function. // function.
return result; return *result;
} }