Revision: 2636
Author: [email protected]
Date: Thu Aug  6 06:35:21 2009
Log: API: added function to find instance of template in prototype chain.

Also inlined Object::IsInstanceOf.

This new function is intended to be used to speed up DOM bindings.

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

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

=======================================
--- /branches/bleeding_edge/include/v8.h        Wed Aug  5 00:59:46 2009
+++ /branches/bleeding_edge/include/v8.h        Thu Aug  6 06:35:21 2009
@@ -1098,6 +1098,12 @@
     */
    Local<Value> GetPrototype();

+  /**
+   * Finds an instance of the given function template in the prototype
+   * chain.
+   */
+  Local<Object> FindInstanceInPrototypeChain(Handle<FunctionTemplate>  
tmpl);
+
    /**
     * Call builtin Object.prototype.toString on this object.
     * This is different from Value::ToString() that may call
=======================================
--- /branches/bleeding_edge/src/api.cc  Tue Aug  4 07:14:01 2009
+++ /branches/bleeding_edge/src/api.cc  Thu Aug  6 06:35:21 2009
@@ -1926,6 +1926,22 @@
    i::Handle<i::Object> result = i::GetPrototype(self);
    return Utils::ToLocal(result);
  }
+
+
+Local<Object> v8::Object::FindInstanceInPrototypeChain(
+    v8::Handle<FunctionTemplate> tmpl) {
+  ON_BAILOUT("v8::Object::FindInstanceInPrototypeChain()",
+             return Local<v8::Object>());
+  ENTER_V8;
+  i::JSObject* object = *Utils::OpenHandle(this);
+  i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
+  while (!object->IsInstanceOf(tmpl_info)) {
+    i::Object* prototype = object->GetPrototype();
+    if (!prototype->IsJSObject()) return Local<Object>();
+    object = i::JSObject::cast(prototype);
+  }
+  return Utils::ToLocal(i::Handle<i::JSObject>(object));
+}


  Local<Array> v8::Object::GetPropertyNames() {
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Wed Jul 29 05:34:21 2009
+++ /branches/bleeding_edge/src/objects-inl.h   Thu Aug  6 06:35:21 2009
@@ -98,6 +98,25 @@
    void holder::set_##name(bool value) {                    \
      set_##field(BooleanBit::set(field(), offset, value));  \
    }
+
+
+bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
+  // There is a constraint on the object; check.
+  if (!this->IsJSObject()) return false;
+  // Fetch the constructor function of the object.
+  Object* cons_obj = JSObject::cast(this)->map()->constructor();
+  if (!cons_obj->IsJSFunction()) return false;
+  JSFunction* fun = JSFunction::cast(cons_obj);
+  // Iterate through the chain of inheriting function templates to
+  // see if the required one occurs.
+  for (Object* type = fun->shared()->function_data();
+       type->IsFunctionTemplateInfo();
+       type = FunctionTemplateInfo::cast(type)->parent_template()) {
+    if (type == expected) return true;
+  }
+  // Didn't find the required type in the inheritance chain.
+  return false;
+}


  bool Object::IsSmi() {
=======================================
--- /branches/bleeding_edge/src/objects.cc      Thu Jul 30 02:13:48 2009
+++ /branches/bleeding_edge/src/objects.cc      Thu Aug  6 06:35:21 2009
@@ -50,24 +50,6 @@
  const int kGetterIndex = 0;
  const int kSetterIndex = 1;

-bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
-  // There is a constraint on the object; check
-  if (!this->IsJSObject()) return false;
-  // Fetch the constructor function of the object
-  Object* cons_obj = JSObject::cast(this)->map()->constructor();
-  if (!cons_obj->IsJSFunction()) return false;
-  JSFunction* fun = JSFunction::cast(cons_obj);
-  // Iterate through the chain of inheriting function templates to
-  // see if the required one occurs.
-  for (Object* type = fun->shared()->function_data();
-       type->IsFunctionTemplateInfo();
-       type = FunctionTemplateInfo::cast(type)->parent_template()) {
-    if (type == expected) return true;
-  }
-  // Didn't find the required type in the inheritance chain.
-  return false;
-}
-

  static Object* CreateJSValue(JSFunction* constructor, Object* value) {
    Object* result = Heap::AllocateJSObject(constructor);
=======================================
--- /branches/bleeding_edge/src/objects.h       Thu Aug  6 03:22:38 2009
+++ /branches/bleeding_edge/src/objects.h       Thu Aug  6 06:35:21 2009
@@ -801,7 +801,7 @@

    // Returns true if this object is an instance of the specified
    // function template.
-  bool IsInstanceOf(FunctionTemplateInfo* type);
+  inline bool IsInstanceOf(FunctionTemplateInfo* type);

    inline bool IsStruct();
  #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name();
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Tue Jul 28 11:11:12 2009
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Thu Aug  6 06:35:21 2009
@@ -631,6 +631,53 @@
      CHECK_EQ(v8_str("[object funky]"), result);
    }
  }
+
+
+THREADED_TEST(FindInstanceInPrototypeChain) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  Local<v8::FunctionTemplate> base = v8::FunctionTemplate::New();
+  Local<v8::FunctionTemplate> derived = v8::FunctionTemplate::New();
+  Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New();
+  derived->Inherit(base);
+
+  Local<v8::Function> base_function = base->GetFunction();
+  Local<v8::Function> derived_function = derived->GetFunction();
+  Local<v8::Function> other_function = other->GetFunction();
+
+  Local<v8::Object> base_instance = base_function->NewInstance();
+  Local<v8::Object> derived_instance = derived_function->NewInstance();
+  Local<v8::Object> derived_instance2 = derived_function->NewInstance();
+  Local<v8::Object> other_instance = other_function->NewInstance();
+  derived_instance2->Set(v8_str("__proto__"), derived_instance);
+  other_instance->Set(v8_str("__proto__"), derived_instance2);
+
+  // base_instance is only an instance of base.
+  CHECK_EQ(base_instance,
+           base_instance->FindInstanceInPrototypeChain(base));
+  CHECK(base_instance->FindInstanceInPrototypeChain(derived).IsEmpty());
+  CHECK(base_instance->FindInstanceInPrototypeChain(other).IsEmpty());
+
+  // derived_instance is an instance of base and derived.
+  CHECK_EQ(derived_instance,
+           derived_instance->FindInstanceInPrototypeChain(base));
+  CHECK_EQ(derived_instance,
+           derived_instance->FindInstanceInPrototypeChain(derived));
+  CHECK(derived_instance->FindInstanceInPrototypeChain(other).IsEmpty());
+
+  // other_instance is an instance of other and its immediate
+  // prototype derived_instance2 is an instance of base and derived.
+  // Note, derived_instance is an instance of base and derived too,
+  // but it comes after derived_instance2 in the prototype chain of
+  // other_instance.
+  CHECK_EQ(derived_instance2,
+           other_instance->FindInstanceInPrototypeChain(base));
+  CHECK_EQ(derived_instance2,
+           other_instance->FindInstanceInPrototypeChain(derived));
+  CHECK_EQ(other_instance,
+           other_instance->FindInstanceInPrototypeChain(other));
+}


  static v8::Handle<Value> handle_property(Local<String> name,

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

Reply via email to