Revision: 2649
Author: [email protected]
Date: Fri Aug 7 04:24:25 2009
Log: Merge r2636 to trunk.
Review URL: http://codereview.chromium.org/164146
http://code.google.com/p/v8/source/detail?r=2649
Modified:
/trunk/include/v8.h
/trunk/src/api.cc
/trunk/src/objects-inl.h
/trunk/src/objects.cc
/trunk/src/objects.h
/trunk/src/version.cc
/trunk/test/cctest/test-api.cc
=======================================
--- /trunk/include/v8.h Wed Aug 5 01:38:10 2009
+++ /trunk/include/v8.h Fri Aug 7 04:24:25 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
=======================================
--- /trunk/src/api.cc Wed Aug 5 01:38:10 2009
+++ /trunk/src/api.cc Fri Aug 7 04:24:25 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() {
=======================================
--- /trunk/src/objects-inl.h Thu Jul 30 07:48:31 2009
+++ /trunk/src/objects-inl.h Fri Aug 7 04:24:25 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() {
=======================================
--- /trunk/src/objects.cc Thu Jul 30 07:48:31 2009
+++ /trunk/src/objects.cc Fri Aug 7 04:24:25 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);
=======================================
--- /trunk/src/objects.h Thu Jul 30 07:48:31 2009
+++ /trunk/src/objects.h Fri Aug 7 04:24:25 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();
=======================================
--- /trunk/src/version.cc Fri Aug 7 03:18:15 2009
+++ /trunk/src/version.cc Fri Aug 7 04:24:25 2009
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 1
#define MINOR_VERSION 3
#define BUILD_NUMBER 2
-#define PATCH_LEVEL 1
+#define PATCH_LEVEL 2
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the
=======================================
--- /trunk/test/cctest/test-api.cc Thu Jul 30 07:48:31 2009
+++ /trunk/test/cctest/test-api.cc Fri Aug 7 04:24:25 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
-~----------~----~----~----~------~----~------~--~---