Revision: 8626
Author:   [email protected]
Date:     Wed Jul 13 04:01:17 2011
Log:      Implement Object.keys for proxies.

[email protected],[email protected]
BUG=
TEST=

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

Modified:
 /branches/bleeding_edge/src/proxy.js
 /branches/bleeding_edge/src/v8natives.js
 /branches/bleeding_edge/test/mjsunit/harmony/proxies.js

=======================================
--- /branches/bleeding_edge/src/proxy.js        Fri Jun  3 03:15:49 2011
+++ /branches/bleeding_edge/src/proxy.js        Wed Jul 13 04:01:17 2011
@@ -135,3 +135,15 @@
 function DerivedHasTrap(name) {
   return !!this.getPropertyDescriptor(name)
 }
+
+function DerivedKeysTrap() {
+  var names = this.getOwnPropertyNames()
+  var enumerableNames = []
+  for (var i = 0, count = 0; i < names.length; ++i) {
+    var name = names[i]
+    if (this.getOwnPropertyDescriptor(TO_STRING_INLINE(name)).enumerable) {
+      enumerableNames[count++] = names[i]
+    }
+  }
+  return enumerableNames
+}
=======================================
--- /branches/bleeding_edge/src/v8natives.js    Thu Jul  7 05:41:20 2011
+++ /branches/bleeding_edge/src/v8natives.js    Wed Jul 13 04:01:17 2011
@@ -308,6 +308,13 @@
 function ObjectKeys(obj) {
   if (!IS_SPEC_OBJECT(obj))
     throw MakeTypeError("obj_ctor_property_non_object", ["keys"]);
+  if (%IsJSProxy(obj)) {
+    var handler = %GetHandler(obj);
+    var keys = handler.keys;
+    if (IS_UNDEFINED(keys)) keys = DerivedKeysTrap;
+    var names = %_CallFunction(handler, keys);
+    return ToStringArray(names);
+  }
   return %LocalKeys(obj);
 }

@@ -585,7 +592,7 @@
       throw MakeTypeError("handler_trap_missing",
                           [handler, "getPropertyDescriptor"]);
     }
-    var descriptor = getProperty.call(handler, p);
+    var descriptor = %_CallFunction(handler, p, getProperty);
     if (IS_UNDEFINED(descriptor)) return descriptor;
     var desc = ToCompletePropertyDescriptor(descriptor);
     if (!desc.configurable) {
@@ -608,7 +615,7 @@
     var handler = %GetHandler(obj);
     var has = handler.has;
     if (IS_UNDEFINED(has)) has = DerivedHasTrap;
-    return ToBoolean(has.call(handler, obj, p));
+    return ToBoolean(%_CallFunction(handler, obj, p, has));
   }
   var desc = GetProperty(obj, p);
   return IS_UNDEFINED(desc) ? false : true;
@@ -636,7 +643,7 @@
   if (IS_UNDEFINED(defineProperty)) {
throw MakeTypeError("handler_trap_missing", [handler, "defineProperty"]);
   }
-  var result = defineProperty.call(handler, p, attributes);
+  var result = %_CallFunction(handler, p, attributes, defineProperty);
   if (!ToBoolean(result)) {
     if (should_throw) {
       throw MakeTypeError("handler_failed", [handler, "defineProperty"]);
@@ -868,7 +875,7 @@
       throw MakeTypeError("handler_trap_missing",
                           [handler, "getOwnPropertyNames"]);
     }
-    var names = getOwnPropertyNames.call(handler);
+    var names = %_CallFunction(handler, getOwnPropertyNames);
     return ToStringArray(names, "getOwnPropertyNames");
   }

=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/proxies.js Thu Jul 7 05:41:20 2011 +++ /branches/bleeding_edge/test/mjsunit/harmony/proxies.js Wed Jul 13 04:01:17 2011
@@ -309,7 +309,7 @@



-// Property names (Object.getOwnPropertyNames).
+// Property names (Object.getOwnPropertyNames, Object.keys).

 function TestPropertyNames(names, handler) {
   var p = Proxy.create(handler)
@@ -331,3 +331,51 @@
     return function() { return [{}] }
   }
 })
+
+
+function TestKeys(names, handler) {
+  var p = Proxy.create(handler)
+  assertArrayEquals(names, Object.keys(p))
+}
+
+TestKeys([], {
+  keys: function() { return [] }
+})
+TestKeys(["a", "zz", " ", "0"], {
+  keys: function() { return ["a", "zz", " ", 0] }
+})
+TestKeys(["throw", "function "], {
+  keys: function() { return this.keys2() },
+  keys2: function() { return ["throw", "function "] }
+})
+TestKeys(["[object Object]"], {
+  get keys() {
+    return function() { return [{}] }
+  }
+})
+TestKeys(["a", "0"], {
+  getOwnPropertyNames: function() { return ["a", 23, "zz", "", 0] },
+ getOwnPropertyDescriptor: function(k) { return {enumerable: k.length == 1} }
+})
+TestKeys(["23", "zz", ""], {
+  getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
+  getOwnPropertyNames2: function() { return ["a", 23, "zz", "", 0] },
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+ getOwnPropertyDescriptor2: function(k) { return {enumerable: k.length != 1} }
+})
+TestKeys(["a", "b", "c", "5"], {
+  get getOwnPropertyNames() {
+    return function() { return ["0", 4, "a", "b", "c", 5] }
+  },
+  get getOwnPropertyDescriptor() {
+    return function(k) { return {enumerable: k >= "44"} }
+  }
+})
+TestKeys([], {
+  get getOwnPropertyNames() {
+    return function() { return ["a", "b", "c"] }
+  },
+  getOwnPropertyDescriptor: function(k) { return {} }
+})

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

Reply via email to