Handlify JSObject::GetProperty????Interceptor.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 10 Oct 2013 15:27:02 +0000 (15:27 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 10 Oct 2013 15:27:02 +0000 (15:27 +0000)
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
src/objects.h
src/runtime.cc
src/stub-cache.cc

index d8a6f13..dc3ac25 100644 (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,
                                              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) {
+  Isolate* isolate = object->GetIsolate();
+
   // TODO(rossberg): Support symbols in the API.
-  if (name->IsSymbol()) return GetHeap()->undefined_value();
+  if (name->IsSymbol()) return isolate->factory()->undefined_value();
 
-  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));
+  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);
 }
 
 
index e0ab984..5d3265b 100644 (file)
@@ -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,
index 26dc36d..4ad9d61 100644 (file)
@@ -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;
 }
 
 
index 4eb6241..f8e09c4 100644 (file)
@@ -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;
 }