Revision: 4797
Author: [email protected]
Date: Fri Jun  4 04:49:44 2010
Log: First phase of migration to new named property query callbacks.

Eventually named 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.

Review URL: http://codereview.chromium.org/2576003
http://code.google.com/p/v8/source/detail?r=4797

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/test/cctest/test-api.cc
 /branches/bleeding_edge/test/cctest/test-debug.cc
 /branches/bleeding_edge/test/cctest/test-decls.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Fri Jun  4 00:53:40 2010
+++ /branches/bleeding_edge/include/v8.h        Fri Jun  4 04:49:44 2010
@@ -1726,13 +1726,22 @@
                                              Local<Value> value,
                                              const AccessorInfo& info);

-
 /**
  * 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 either boolean (true if property exists and false
+ * otherwise) or an integer encoding property attributes.
  */
+#ifdef USE_NEW_QUERY_CALLBACKS
+typedef Handle<Integer> (*NamedPropertyQuery)(Local<String> property,
+                                              const AccessorInfo& info);
+#else
 typedef Handle<Boolean> (*NamedPropertyQuery)(Local<String> property,
                                               const AccessorInfo& info);
+#endif
+
+typedef Handle<Value> (*NamedPropertyQueryImpl)(Local<String> property,
+                                                const AccessorInfo& info);
+


 /**
@@ -1984,7 +1993,16 @@
                                        NamedPropertyQuery query,
                                        NamedPropertyDeleter remover,
                                        NamedPropertyEnumerator enumerator,
-                                       Handle<Value> data);
+                                       Handle<Value> data) {
+    NamedPropertyQueryImpl casted =
+        reinterpret_cast<NamedPropertyQueryImpl>(query);
+    SetNamedInstancePropertyHandlerImpl(getter,
+                                        setter,
+                                        casted,
+                                        remover,
+                                        enumerator,
+                                        data);
+  }
   void SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter,
                                          IndexedPropertySetter setter,
                                          IndexedPropertyQuery query,
@@ -1996,6 +2014,13 @@

   friend class Context;
   friend class ObjectTemplate;
+ private:
+  void SetNamedInstancePropertyHandlerImpl(NamedPropertyGetter getter,
+                                           NamedPropertySetter setter,
+                                           NamedPropertyQueryImpl query,
+                                           NamedPropertyDeleter remover,
+ NamedPropertyEnumerator enumerator,
+                                           Handle<Value> data);
 };


@@ -2053,7 +2078,7 @@
    *
    * \param getter The callback to invoke when getting a property.
    * \param setter The callback to invoke when setting a property.
- * \param query The callback to invoke to check is an object has a property. + * \param query The callback to invoke to check if an object has a property.
    * \param deleter The callback to invoke when deleting a property.
    * \param enumerator The callback to invoke to enumerate all the named
    *   properties of an object.
@@ -2065,7 +2090,26 @@
                                NamedPropertyQuery query = 0,
                                NamedPropertyDeleter deleter = 0,
                                NamedPropertyEnumerator enumerator = 0,
-                               Handle<Value> data = Handle<Value>());
+                               Handle<Value> data = Handle<Value>()) {
+    NamedPropertyQueryImpl casted =
+        reinterpret_cast<NamedPropertyQueryImpl>(query);
+    SetNamedPropertyHandlerImpl(getter,
+                                setter,
+                                casted,
+                                deleter,
+                                enumerator,
+                                data);
+  }
+
+ private:
+  void SetNamedPropertyHandlerImpl(NamedPropertyGetter getter,
+                                   NamedPropertySetter setter,
+                                   NamedPropertyQueryImpl query,
+                                   NamedPropertyDeleter deleter,
+                                   NamedPropertyEnumerator enumerator,
+                                   Handle<Value> data);
+
+ public:

   /**
    * Sets an indexed property handler on the object template.
=======================================
--- /branches/bleeding_edge/src/api.cc  Tue May 25 05:14:49 2010
+++ /branches/bleeding_edge/src/api.cc  Fri Jun  4 04:49:44 2010
@@ -853,10 +853,10 @@
 }


-void FunctionTemplate::SetNamedInstancePropertyHandler(
+void FunctionTemplate::SetNamedInstancePropertyHandlerImpl(
       NamedPropertyGetter getter,
       NamedPropertySetter setter,
-      NamedPropertyQuery query,
+      NamedPropertyQueryImpl query,
       NamedPropertyDeleter remover,
       NamedPropertyEnumerator enumerator,
       Handle<Value> data) {
@@ -987,12 +987,13 @@
 }


-void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
-                                             NamedPropertySetter setter,
-                                             NamedPropertyQuery query,
-                                             NamedPropertyDeleter remover,
- NamedPropertyEnumerator enumerator,
-                                             Handle<Value> data) {
+void ObjectTemplate::SetNamedPropertyHandlerImpl(NamedPropertyGetter getter, + NamedPropertySetter setter, + NamedPropertyQueryImpl query, + NamedPropertyDeleter remover,
+                                                 NamedPropertyEnumerator
+                                                    enumerator,
+                                                 Handle<Value> data) {
   if (IsDeadCheck("v8::ObjectTemplate::SetNamedPropertyHandler()")) return;
   ENTER_V8;
   HandleScope scope;
@@ -1000,12 +1001,12 @@
   i::FunctionTemplateInfo* constructor =
i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
-  Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
-                                                        setter,
-                                                        query,
-                                                        remover,
-                                                        enumerator,
-                                                        data);
+  Utils::ToLocal(cons)->SetNamedInstancePropertyHandlerImpl(getter,
+                                                            setter,
+                                                            query,
+                                                            remover,
+                                                            enumerator,
+                                                            data);
 }


=======================================
--- /branches/bleeding_edge/src/objects.cc      Wed Jun  2 01:58:44 2010
+++ /branches/bleeding_edge/src/objects.cc      Fri Jun  4 04:49:44 2010
@@ -2013,19 +2013,25 @@
   CustomArguments args(interceptor->data(), receiver, this);
   v8::AccessorInfo info(args.end());
   if (!interceptor->query()->IsUndefined()) {
-    v8::NamedPropertyQuery query =
-        v8::ToCData<v8::NamedPropertyQuery>(interceptor->query());
+    v8::NamedPropertyQueryImpl query =
+        v8::ToCData<v8::NamedPropertyQueryImpl>(interceptor->query());
LOG(ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name));
-    v8::Handle<v8::Boolean> result;
+    v8::Handle<v8::Value> result;
     {
       // Leaving JavaScript.
       VMState state(EXTERNAL);
       result = query(v8::Utils::ToLocal(name_handle), info);
     }
     if (!result.IsEmpty()) {
-      // Convert the boolean result to a property attribute
-      // specification.
-      return result->IsTrue() ? NONE : ABSENT;
+      // Temporary complicated logic, would be removed soon.
+      if (result->IsBoolean()) {
+        // Convert the boolean result to a property attribute
+        // specification.
+        return result->IsTrue() ? NONE : ABSENT;
+      } else {
+        ASSERT(result->IsInt32());
+        return static_cast<PropertyAttributes>(result->Int32Value());
+      }
     }
   } else if (!interceptor->getter()->IsUndefined()) {
     v8::NamedPropertyGetter getter =
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Fri May 28 04:54:58 2010
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Fri Jun  4 04:49:44 2010
@@ -27,6 +27,8 @@

 #include <limits.h>

+#define USE_NEW_QUERY_CALLBACKS
+
 #include "v8.h"

 #include "api.h"
@@ -1120,11 +1122,11 @@
 }


-v8::Handle<v8::Boolean> CheckThisNamedPropertyQuery(Local<String> property,
+v8::Handle<v8::Integer> CheckThisNamedPropertyQuery(Local<String> property,
const AccessorInfo& info) {
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
-  return v8::Handle<v8::Boolean>();
+  return v8::Handle<v8::Integer>();
 }


@@ -1221,13 +1223,13 @@
 }


-static v8::Handle<v8::Boolean> PrePropertyHandlerHas(Local<String> key,
-                                                     const AccessorInfo&) {
+static v8::Handle<v8::Integer> PrePropertyHandlerQuery(Local<String> key,
+ const AccessorInfo&) {
   if (v8_str("pre")->Equals(key)) {
-    return v8::True();
+    return v8::Integer::New(v8::None);
   }

-  return v8::Handle<v8::Boolean>();  // do not intercept the call
+  return v8::Handle<v8::Integer>();  // do not intercept the call
 }


@@ -1236,7 +1238,7 @@
   v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New();
   desc->InstanceTemplate()->SetNamedPropertyHandler(PrePropertyHandlerGet,
                                                     0,
-                                                    PrePropertyHandlerHas);
+ PrePropertyHandlerQuery);
   LocalContext env(NULL, desc->InstanceTemplate());
   Script::Compile(v8_str(
       "var pre = 'Object: pre'; var on = 'Object: on';"))->Run();
=======================================
--- /branches/bleeding_edge/test/cctest/test-debug.cc Thu May 20 10:15:46 2010 +++ /branches/bleeding_edge/test/cctest/test-debug.cc Fri Jun 4 04:49:44 2010
@@ -27,6 +27,8 @@

 #include <stdlib.h>

+#define USE_NEW_QUERY_CALLBACKS
+
 #include "v8.h"

 #include "api.h"
=======================================
--- /branches/bleeding_edge/test/cctest/test-decls.cc Tue Aug 18 05:43:36 2009 +++ /branches/bleeding_edge/test/cctest/test-decls.cc Fri Jun 4 04:49:44 2010
@@ -27,6 +27,8 @@

 #include <stdlib.h>

+#define USE_NEW_QUERY_CALLBACKS
+
 #include "v8.h"

 #include "heap.h"
@@ -63,12 +65,12 @@

   int get_count() const { return get_count_; }
   int set_count() const { return set_count_; }
-  int has_count() const { return has_count_; }
+  int query_count() const { return query_count_; }

  protected:
   virtual v8::Handle<Value> Get(Local<String> key);
   virtual v8::Handle<Value> Set(Local<String> key, Local<Value> value);
-  virtual v8::Handle<Boolean> Has(Local<String> key);
+  virtual v8::Handle<Integer> Query(Local<String> key);

   void InitializeIfNeeded();

@@ -85,8 +87,8 @@
   static v8::Handle<Value> HandleSet(Local<String> key,
                                      Local<Value> value,
                                      const AccessorInfo& info);
-  static v8::Handle<Boolean> HandleHas(Local<String> key,
-                                       const AccessorInfo& info);
+  static v8::Handle<Integer> HandleQuery(Local<String> key,
+                                         const AccessorInfo& info);

  private:
   bool is_initialized_;
@@ -95,14 +97,14 @@

   int get_count_;
   int set_count_;
-  int has_count_;
+  int query_count_;

   static DeclarationContext* GetInstance(const AccessorInfo& info);
 };


 DeclarationContext::DeclarationContext()
-    : is_initialized_(false), get_count_(0), set_count_(0), has_count_(0) {
+ : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) {
   // Do nothing.
 }

@@ -114,7 +116,7 @@
   Local<Value> data = External::New(this);
   GetHolder(function)->SetNamedPropertyHandler(&HandleGet,
                                                &HandleSet,
-                                               &HandleHas,
+                                               &HandleQuery,
                                                0, 0,
                                                data);
   context_ = Context::New(0, function->InstanceTemplate(), Local<Value>());
@@ -124,7 +126,7 @@


 void DeclarationContext::Check(const char* source,
-                               int get, int set, int has,
+                               int get, int set, int query,
                                Expectations expectations,
                                v8::Handle<Value> value) {
   InitializeIfNeeded();
@@ -137,7 +139,7 @@
   Local<Value> result = Script::Compile(String::New(source))->Run();
   CHECK_EQ(get, get_count());
   CHECK_EQ(set, set_count());
-  CHECK_EQ(has, has_count());
+  CHECK_EQ(query, query_count());
   if (expectations == EXPECT_RESULT) {
     CHECK(!catcher.HasCaught());
     if (!value.IsEmpty()) {
@@ -170,11 +172,11 @@
 }


-v8::Handle<Boolean> DeclarationContext::HandleHas(Local<String> key,
- const AccessorInfo& info) {
+v8::Handle<Integer> DeclarationContext::HandleQuery(Local<String> key,
+ const AccessorInfo& info) {
   DeclarationContext* context = GetInstance(info);
-  context->has_count_++;
-  return context->Has(key);
+  context->query_count_++;
+  return context->Query(key);
 }


@@ -194,8 +196,8 @@
 }


-v8::Handle<Boolean> DeclarationContext::Has(Local<String> key) {
-  return v8::Handle<Boolean>();
+v8::Handle<Integer> DeclarationContext::Query(Local<String> key) {
+  return v8::Handle<Integer>();
 }


@@ -249,8 +251,8 @@

 class PresentPropertyContext: public DeclarationContext {
  protected:
-  virtual v8::Handle<Boolean> Has(Local<String> key) {
-    return True();
+  virtual v8::Handle<Integer> Query(Local<String> key) {
+    return Integer::New(v8::None);
   }
 };

@@ -304,8 +306,8 @@

 class AbsentPropertyContext: public DeclarationContext {
  protected:
-  virtual v8::Handle<Boolean> Has(Local<String> key) {
-    return False();
+  virtual v8::Handle<Integer> Query(Local<String> key) {
+    return v8::Handle<Integer>();
   }
 };

@@ -316,7 +318,7 @@
   { AbsentPropertyContext context;
     context.Check("var x; x",
                   1,  // access
-                  2,  // declaration + initialization
+                  1,  // declaration
                   2,  // declaration + initialization
                   EXPECT_RESULT, Undefined());
   }
@@ -375,24 +377,24 @@
   AppearingPropertyContext() : state_(DECLARE) { }

  protected:
-  virtual v8::Handle<Boolean> Has(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<String> key) {
     switch (state_) {
       case DECLARE:
         // Force declaration by returning that the
         // property is absent.
         state_ = INITIALIZE_IF_ASSIGN;
-        return False();
+        return Handle<Integer>();
       case INITIALIZE_IF_ASSIGN:
         // Return that the property is present so we only get the
         // setter called when initializing with a value.
         state_ = UNKNOWN;
-        return True();
+        return Integer::New(v8::None);
       default:
         CHECK(state_ == UNKNOWN);
         break;
     }
     // Do the lookup in the object.
-    return v8::Local<Boolean>();
+    return v8::Handle<Integer>();
   }

  private:
@@ -458,31 +460,31 @@
   ReappearingPropertyContext() : state_(DECLARE) { }

  protected:
-  virtual v8::Handle<Boolean> Has(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<String> key) {
     switch (state_) {
       case DECLARE:
         // Force the first declaration by returning that
         // the property is absent.
         state_ = DONT_DECLARE;
-        return False();
+        return Handle<Integer>();
       case DONT_DECLARE:
         // Ignore the second declaration by returning
         // that the property is already there.
         state_ = INITIALIZE;
-        return True();
+        return Integer::New(v8::None);
       case INITIALIZE:
         // Force an initialization by returning that
         // the property is absent. This will make sure
         // that the setter is called and it will not
         // lead to redeclaration conflicts (yet).
         state_ = UNKNOWN;
-        return False();
+        return Handle<Integer>();
       default:
         CHECK(state_ == UNKNOWN);
         break;
     }
     // Do the lookup in the object.
-    return v8::Local<Boolean>();
+    return Handle<Integer>();
   }

  private:
@@ -506,9 +508,9 @@

 class ExistsInPrototypeContext: public DeclarationContext {
  protected:
-  virtual v8::Handle<Boolean> Has(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<String> key) {
     // Let it seem that the property exists in the prototype object.
-    return True();
+    return Integer::New(v8::None);
   }

   // Use the prototype as the holder for the interceptors.
@@ -568,9 +570,9 @@

 class AbsentInPrototypeContext: public DeclarationContext {
  protected:
-  virtual v8::Handle<Boolean> Has(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<String> key) {
     // Let it seem that the property is absent in the prototype object.
-    return False();
+    return Handle<Integer>();
   }

   // Use the prototype as the holder for the interceptors.

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to