From e08ce319ca6ef49b68dc66321d92d9265de08abc Mon Sep 17 00:00:00 2001 From: "christian.plesner.hansen@gmail.com" Date: Thu, 23 Oct 2008 10:31:49 +0000 Subject: [PATCH] Added v8::Object::GetProperties method that returns an array of all the enumerable properties of an object. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@568 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 8 ++++++++ src/api.cc | 14 ++++++++++++++ test/cctest/test-api.cc | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/include/v8.h b/include/v8.h index d463393fd..70b1f526c 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1022,6 +1022,14 @@ class EXPORT Object : public Value { bool Has(uint32_t index); bool Delete(uint32_t index); + /** + * Returns an array containing the names of the enumerable properties + * of this object, including properties from prototype objects. The + * array returned by this method contains the same values as would + * be enumerated by a for-in statement over this object. + */ + Local GetPropertyNames(); + /** * Get the prototype object. This does not skip objects marked to * be skipped by __proto__ and it does not consult the security diff --git a/src/api.cc b/src/api.cc index b4dd60edb..5899c5173 100644 --- a/src/api.cc +++ b/src/api.cc @@ -1750,6 +1750,20 @@ Local v8::Object::GetPrototype() { } +Local v8::Object::GetPropertyNames() { + ON_BAILOUT("v8::Object::GetPropertyNames()", return Local()); + v8::HandleScope scope; + i::Handle self = Utils::OpenHandle(this); + i::Handle value = i::GetKeysInFixedArrayFor(self); + // Because we use caching to speed up enumeration it is important + // to never change the result of the basic enumeration function so + // we clone the result. + i::Handle elms = i::Factory::CopyFixedArray(value); + i::Handle result = i::Factory::NewJSArrayWithElements(elms); + return scope.Close(Utils::ToLocal(result)); +} + + Local v8::Object::ObjectProtoToString() { ON_BAILOUT("v8::Object::ObjectProtoToString()", return Local()); i::Handle self = Utils::OpenHandle(this); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index ccbaa9911..c9d6c6978 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -5033,3 +5033,44 @@ THREADED_TEST(DateAccess) { CHECK(date->IsDate()); CHECK_EQ(1224744689038.0, v8::Handle::Cast(date)->NumberValue()); } + + +void CheckProperties(v8::Handle val, int elmc, const char* elmv[]) { + v8::Handle obj = v8::Handle::Cast(val); + v8::Handle props = obj->GetPropertyNames(); + CHECK_EQ(elmc, props->Length()); + for (int i = 0; i < elmc; i++) { + v8::String::Utf8Value elm(props->Get(v8::Integer::New(i))); + CHECK_EQ(elmv[i], *elm); + } +} + + +THREADED_TEST(PropertyEnumeration) { + v8::HandleScope scope; + LocalContext context; + v8::Handle obj = v8::Script::Compile(v8::String::New( + "var result = [];" + "result[0] = {};" + "result[1] = {a: 1, b: 2};" + "result[2] = [1, 2, 3];" + "var proto = {x: 1, y: 2, z: 3};" + "var x = { __proto__: proto, w: 0, z: 1 };" + "result[3] = x;" + "result;" + ))->Run(); + v8::Handle elms = v8::Handle::Cast(obj); + CHECK_EQ(4, elms->Length()); + int elmc0 = 0; + const char** elmv0 = NULL; + CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0); + int elmc1 = 2; + const char* elmv1[] = {"a", "b"}; + CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); + int elmc2 = 3; + const char* elmv2[] = {"0", "1", "2"}; + CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); + int elmc3 = 4; + const char* elmv3[] = {"w", "z", "x", "y"}; + CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); +} -- 2.34.1