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:
parent
caeb19fa28
commit
995ea2bd82
@ -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,
|
||||
Name* name,
|
||||
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,
|
||||
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<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 NONEXISTENT:
|
||||
UNREACHABLE();
|
||||
@ -12951,21 +12973,26 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() {
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* JSObject::GetPropertyPostInterceptor(
|
||||
Object* receiver,
|
||||
Name* name,
|
||||
Handle<Object> JSObject::GetPropertyPostInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> 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<Object> result;
|
||||
if (lookup.IsFound()) {
|
||||
result = GetProperty(object, receiver, &lookup, name, attributes);
|
||||
} else {
|
||||
// Continue searching via the prototype chain.
|
||||
Handle<Object> 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<Object> JSObject::GetPropertyWithInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> 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<Object> receiver_handle(receiver, isolate);
|
||||
Handle<JSObject> holder_handle(this);
|
||||
Handle<String> name_handle(String::cast(name));
|
||||
// TODO(rossberg): Support symbols in the API.
|
||||
if (name->IsSymbol()) return isolate->factory()->undefined_value();
|
||||
|
||||
Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor(), isolate);
|
||||
Handle<String> name_string = Handle<String>::cast(name);
|
||||
|
||||
if (!interceptor->getter()->IsUndefined()) {
|
||||
v8::NamedPropertyGetterCallback getter =
|
||||
v8::ToCData<v8::NamedPropertyGetterCallback>(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<v8::Value> 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<Object> 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<Object> GetPropertyWithReceiver(Handle<Object> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> 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<Object> GetPropertyWithInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
PropertyAttributes* attributes);
|
||||
MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor(
|
||||
Object* receiver,
|
||||
Name* name,
|
||||
static Handle<Object> GetPropertyPostInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
PropertyAttributes* attributes);
|
||||
MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
|
||||
Object* receiver,
|
||||
|
@ -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<Object> result =
|
||||
JSObject::GetPropertyWithInterceptor(obj, obj, name, &attributes);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate, result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1223,8 +1223,8 @@ static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) {
|
||||
}
|
||||
|
||||
|
||||
static MaybeObject* LoadWithInterceptor(Arguments* args,
|
||||
PropertyAttributes* attrs) {
|
||||
static Handle<Object> LoadWithInterceptor(Arguments* args,
|
||||
PropertyAttributes* attrs) {
|
||||
ASSERT(args->length() == StubCache::kInterceptorArgsLength);
|
||||
Handle<Name> name_handle =
|
||||
args->at<Name>(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<String> name = Handle<String>::cast(name_handle);
|
||||
|
||||
Address getter_address = v8::ToCData<Address>(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<v8::Value> 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<Object> 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<Object> 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<Object> 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<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
|
||||
// will lead to an exception when trying to invoke the result as a
|
||||
// function.
|
||||
return result;
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user