First phase of migration to new indexed property query callbacks.
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 10 Aug 2010 10:05:18 +0000 (10:05 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 10 Aug 2010 10:05:18 +0000 (10:05 +0000)
Eventually indexed property query callbacks will return attributes
(as an integer) or an empty handle if property is not intercepted.

To gradually migrate to this new API, USE_NEW_QUERY_CALLBACK
macro would control if old or new style API is used.

So the migration plan is:

1) introduce new API which should be explictily enabled;
2) switch to new API defining USE_NEW_QUERY_CALLBACK before
include of <v8.h> (that would require changes to client code as well)
3) remove old API from v8
4) remove #define USE_NEW_QUERY_CALLBACK from clients.

BUG=http://code.google.com/p/v8/issues/detail?id=816

Review URL: http://codereview.chromium.org/3101001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5228 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8.h
src/api.cc
src/objects.cc
test/cctest/test-api.cc

index b22e3d1..20cef79 100644 (file)
@@ -1824,10 +1824,19 @@ typedef Handle<Value> (*IndexedPropertySetter)(uint32_t index,
 
 /**
  * Returns a non-empty handle if the interceptor intercepts the request.
- * The result is true if the property exists and false otherwise.
+ * The result is true if either a boolean (true if property exists and false
+ * otherwise) or an integer encoding property attributes.
  */
+#ifdef USE_NEW_QUERY_CALLBACKS
+typedef Handle<Integer> (*IndexedPropertyQuery)(uint32_t index,
+                                                const AccessorInfo& info);
+#else
 typedef Handle<Boolean> (*IndexedPropertyQuery)(uint32_t index,
                                                 const AccessorInfo& info);
+#endif
+
+typedef Handle<Value> (*IndexedPropertyQueryImpl)(uint32_t index,
+                                                  const AccessorInfo& info);
 
 /**
  * Returns a non-empty handle if the deleter intercepts the request.
@@ -2045,7 +2054,23 @@ class V8EXPORT FunctionTemplate : public Template {
                                          IndexedPropertyQuery query,
                                          IndexedPropertyDeleter remover,
                                          IndexedPropertyEnumerator enumerator,
-                                         Handle<Value> data);
+                                         Handle<Value> data) {
+    IndexedPropertyQueryImpl casted =
+        reinterpret_cast<IndexedPropertyQueryImpl>(query);
+    SetIndexedInstancePropertyHandlerImpl(getter,
+                                          setter,
+                                          casted,
+                                          remover,
+                                          enumerator,
+                                          data);
+  }
+  void SetIndexedInstancePropertyHandlerImpl(
+      IndexedPropertyGetter getter,
+      IndexedPropertySetter setter,
+      IndexedPropertyQueryImpl query,
+      IndexedPropertyDeleter remover,
+      IndexedPropertyEnumerator enumerator,
+      Handle<Value> data);
   void SetInstanceCallAsFunctionHandler(InvocationCallback callback,
                                         Handle<Value> data);
 
@@ -2144,7 +2169,25 @@ class V8EXPORT ObjectTemplate : public Template {
                                  IndexedPropertyQuery query = 0,
                                  IndexedPropertyDeleter deleter = 0,
                                  IndexedPropertyEnumerator enumerator = 0,
-                                 Handle<Value> data = Handle<Value>());
+                                 Handle<Value> data = Handle<Value>()) {
+    IndexedPropertyQueryImpl casted =
+        reinterpret_cast<IndexedPropertyQueryImpl>(query);
+    SetIndexedPropertyHandlerImpl(getter,
+                                  setter,
+                                  casted,
+                                  deleter,
+                                  enumerator,
+                                  data);
+  }
+ private:
+  void SetIndexedPropertyHandlerImpl(IndexedPropertyGetter getter,
+                                     IndexedPropertySetter setter,
+                                     IndexedPropertyQueryImpl query,
+                                     IndexedPropertyDeleter deleter,
+                                     IndexedPropertyEnumerator enumerator,
+                                     Handle<Value> data);
+ public:
+
   /**
    * Sets the callback to be used when calling instances created from
    * this template as a function.  If no callback is set, instances
index 4bd5699..b3164dd 100644 (file)
@@ -886,10 +886,10 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
 }
 
 
-void FunctionTemplate::SetIndexedInstancePropertyHandler(
+void FunctionTemplate::SetIndexedInstancePropertyHandlerImpl(
       IndexedPropertyGetter getter,
       IndexedPropertySetter setter,
-      IndexedPropertyQuery query,
+      IndexedPropertyQueryImpl query,
       IndexedPropertyDeleter remover,
       IndexedPropertyEnumerator enumerator,
       Handle<Value> data) {
@@ -1054,10 +1054,10 @@ void ObjectTemplate::SetAccessCheckCallbacks(
 }
 
 
-void ObjectTemplate::SetIndexedPropertyHandler(
+void ObjectTemplate::SetIndexedPropertyHandlerImpl(
       IndexedPropertyGetter getter,
       IndexedPropertySetter setter,
-      IndexedPropertyQuery query,
+      IndexedPropertyQueryImpl query,
       IndexedPropertyDeleter remover,
       IndexedPropertyEnumerator enumerator,
       Handle<Value> data) {
@@ -1068,12 +1068,12 @@ void ObjectTemplate::SetIndexedPropertyHandler(
   i::FunctionTemplateInfo* constructor =
       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
-  Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
-                                                          setter,
-                                                          query,
-                                                          remover,
-                                                          enumerator,
-                                                          data);
+  Utils::ToLocal(cons)->SetIndexedInstancePropertyHandlerImpl(getter,
+                                                              setter,
+                                                              query,
+                                                              remover,
+                                                              enumerator,
+                                                              data);
 }
 
 
index 4e20959..aabb041 100644 (file)
@@ -5823,16 +5823,24 @@ bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) {
   CustomArguments args(interceptor->data(), receiver, this);
   v8::AccessorInfo info(args.end());
   if (!interceptor->query()->IsUndefined()) {
-    v8::IndexedPropertyQuery query =
-        v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query());
+    v8::IndexedPropertyQueryImpl query =
+        v8::ToCData<v8::IndexedPropertyQueryImpl>(interceptor->query());
     LOG(ApiIndexedPropertyAccess("interceptor-indexed-has", this, index));
-    v8::Handle<v8::Boolean> result;
+    v8::Handle<v8::Value> result;
     {
       // Leaving JavaScript.
       VMState state(EXTERNAL);
       result = query(index, info);
     }
-    if (!result.IsEmpty()) return result->IsTrue();
+    if (!result.IsEmpty()) {
+      // IsBoolean check would be removed when transition to new API is over.
+      if (result->IsBoolean()) {
+        return result->IsTrue() ? true : false;
+      } else {
+        ASSERT(result->IsInt32());
+        return true;  // absence of property is signaled by empty handle.
+      }
+    }
   } else if (!interceptor->getter()->IsUndefined()) {
     v8::IndexedPropertyGetter getter =
         v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
index 82b93c9..47a55e6 100644 (file)
@@ -27,6 +27,8 @@
 
 #include <limits.h>
 
+#define USE_NEW_QUERY_CALLBACKS
+
 #include "v8.h"
 
 #include "api.h"
@@ -1194,12 +1196,12 @@ v8::Handle<Value> CheckThisNamedPropertySetter(Local<String> property,
   return v8::Handle<Value>();
 }
 
-v8::Handle<v8::Boolean> CheckThisIndexedPropertyQuery(
+v8::Handle<v8::Integer> CheckThisIndexedPropertyQuery(
     uint32_t index,
     const AccessorInfo& info) {
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
-  return v8::Handle<v8::Boolean>();
+  return v8::Handle<v8::Integer>();
 }