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,
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user