Added v8::Object::GetProperties method that returns an array of all
authorchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Oct 2008 10:31:49 +0000 (10:31 +0000)
committerchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Oct 2008 10:31:49 +0000 (10:31 +0000)
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
src/api.cc
test/cctest/test-api.cc

index d463393fd8a8dcff44452da7f769d992994fe255..70b1f526c3f34f182041477979f094ff9cbc9b92 100644 (file)
@@ -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<Array> GetPropertyNames();
+
   /**
    * Get the prototype object.  This does not skip objects marked to
    * be skipped by __proto__ and it does not consult the security
index b4dd60edba382000d89417ac79f99ae905a25017..5899c51734a697fe03d25f9f8a31740a1bbf5605 100644 (file)
@@ -1750,6 +1750,20 @@ Local<Value> v8::Object::GetPrototype() {
 }
 
 
+Local<Array> v8::Object::GetPropertyNames() {
+  ON_BAILOUT("v8::Object::GetPropertyNames()", return Local<v8::Array>());
+  v8::HandleScope scope;
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  i::Handle<i::FixedArray> 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<i::FixedArray> elms = i::Factory::CopyFixedArray(value);
+  i::Handle<i::JSArray> result = i::Factory::NewJSArrayWithElements(elms);
+  return scope.Close(Utils::ToLocal(result));
+}
+
+
 Local<String> v8::Object::ObjectProtoToString() {
   ON_BAILOUT("v8::Object::ObjectProtoToString()", return Local<v8::String>());
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
index ccbaa9911cbe581cc290287ffb15b3a602ed41ac..c9d6c6978df79a2fa8eec1cb0e370cf5fd7e2d7c 100644 (file)
@@ -5033,3 +5033,44 @@ THREADED_TEST(DateAccess) {
   CHECK(date->IsDate());
   CHECK_EQ(1224744689038.0, v8::Handle<v8::Date>::Cast(date)->NumberValue());
 }
+
+
+void CheckProperties(v8::Handle<v8::Value> val, int elmc, const char* elmv[]) {
+  v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(val);
+  v8::Handle<v8::Array> 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<v8::Value> 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<v8::Array> elms = v8::Handle<v8::Array>::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);
+}