Revision: 8630
Author:   [email protected]
Date:     Wed Jul 13 04:57:15 2011
Log:      Implement Object.getOwnPropertyDescriptor for proxies.
Fix bug in compilation of calls with proxy receivers.

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

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

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

=======================================
--- /branches/bleeding_edge/src/property.h      Thu May 19 04:47:34 2011
+++ /branches/bleeding_edge/src/property.h      Wed Jul 13 04:57:15 2011
@@ -206,6 +206,7 @@
     lookup_type_ = HANDLER_TYPE;
     holder_ = NULL;
     details_ = PropertyDetails(NONE, HANDLER);
+    cacheable_ = false;
   }

   void InterceptorResult(JSObject* holder) {
=======================================
--- /branches/bleeding_edge/src/v8natives.js    Wed Jul 13 04:01:17 2011
+++ /branches/bleeding_edge/src/v8natives.js    Wed Jul 13 04:57:15 2011
@@ -595,7 +595,7 @@
     var descriptor = %_CallFunction(handler, p, getProperty);
     if (IS_UNDEFINED(descriptor)) return descriptor;
     var desc = ToCompletePropertyDescriptor(descriptor);
-    if (!desc.configurable) {
+    if (!desc.isConfigurable()) {
       throw MakeTypeError("proxy_prop_not_configurable",
[handler, "getPropertyDescriptor", p, descriptor]);
     }
@@ -624,6 +624,23 @@

 // ES5 section 8.12.1.
 function GetOwnProperty(obj, p) {
+  if (%IsJSProxy(obj)) {
+    var handler = %GetHandler(obj);
+    var getOwnProperty = handler.getOwnPropertyDescriptor;
+    if (IS_UNDEFINED(getOwnProperty)) {
+      throw MakeTypeError("handler_trap_missing",
+                          [handler, "getOwnPropertyDescriptor"]);
+    }
+    var descriptor = %_CallFunction(handler, p, getOwnProperty);
+    if (IS_UNDEFINED(descriptor)) return descriptor;
+    var desc = ToCompletePropertyDescriptor(descriptor);
+    if (!desc.isConfigurable()) {
+      throw MakeTypeError("proxy_prop_not_configurable",
+ [handler, "getOwnPropertyDescriptor", p, descriptor]);
+    }
+    return desc;
+  }
+
   // GetOwnProperty returns an array indexed by the constants
   // defined in macros.py.
   // If p is not a property on obj undefined is returned.
@@ -836,7 +853,8 @@
 // ES5 section 15.2.3.3
 function ObjectGetOwnPropertyDescriptor(obj, p) {
   if (!IS_SPEC_OBJECT(obj))
- throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyDescriptor"]);
+    throw MakeTypeError("obj_ctor_property_non_object",
+                        ["getOwnPropertyDescriptor"]);
   var desc = GetOwnProperty(obj, p);
   return FromPropertyDescriptor(desc);
 }
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/proxies.js Wed Jul 13 04:01:17 2011 +++ /branches/bleeding_edge/test/mjsunit/harmony/proxies.js Wed Jul 13 04:57:15 2011
@@ -35,7 +35,6 @@
   var o = Proxy.create(handler)
   assertEquals(42, o.a)
   assertEquals(42, o["b"])
-//  assertEquals(Object.getOwnPropertyDescriptor(o, "b").value, 42)
 }

 TestGet({
@@ -69,6 +68,64 @@
 }))


+function TestGetCall(handler) {
+  var p = Proxy.create(handler)
+  assertEquals(55, p.f())
+  assertEquals(55, p.f("unused", "arguments"))
+  assertEquals(55, p.f.call(p))
+  assertEquals(55, p.withargs(45, 5))
+  assertEquals(55, p.withargs.call(p, 11, 22))
+  assertEquals("6655", "66" + p)  // calls p.toString
+}
+
+TestGetCall({
+  get: function(r, k) { return function() { return 55 } }
+})
+TestGetCall({
+  get: function(r, k) { return this.get2(r, k) },
+  get2: function(r, k) { return function() { return 55 } }
+})
+TestGetCall({
+  getPropertyDescriptor: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+ getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
+  getPropertyDescriptor2: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+  getPropertyDescriptor: function(k) {
+    return {get value() { return function() { return 55 } }}
+  }
+})
+TestGetCall({
+  get: undefined,
+  getPropertyDescriptor: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+  get: function(r, k) {
+    if (k == "gg") {
+      return function() { return 55 }
+    } else if (k == "withargs") {
+      return function(n, m) { return n + m * 2 }
+    } else {
+      return function() { return this.gg() }
+    }
+  }
+})
+
+TestGetCall(Proxy.create({
+  get: function(pr, pk) {
+    return function(r, k) { return function() { return 55 } }
+  }
+}))
+
+

 // Setters.

@@ -82,9 +139,6 @@
   assertEquals(43, o["b"] = 43)
   assertEquals("b", key)
   assertEquals(43, val)
-//  assertTrue(Object.defineProperty(o, "c", {value: 44}))
-//  assertEquals("c", key)
-//  assertEquals(44, val)
 }

 TestSet({
@@ -149,7 +203,7 @@



-// Property definition (Object.defineProperty).
+// Property definition (Object.defineProperty and Object.defineProperties).

 var key
 var desc
@@ -193,7 +247,7 @@
   assertEquals("zzz", key)
   assertEquals(0, Object.getOwnPropertyNames(desc).length)

-// This test requires [s in proxy] to be implemented first.
+// TODO(rossberg): This test requires [s in proxy] to be implemented first.
 //  var d = Proxy.create({
 //    get: function(r, k) { return (k === "value") ? 77 : void 0 },
 //    getOwnPropertyNames: function() { return ["value"] }
@@ -204,6 +258,20 @@
 //  assertEquals("p", key)
 //  assertEquals(1, Object.getOwnPropertyNames(desc).length)
 //  assertEquals(77, desc.value)
+
+  var props = {
+    'bla': {},
+    blub: {get: function() { return true }},
+    '': {get value() { return 20 }},
+    last: {value: 21, configurable: true, mine: "eyes"}
+  }
+ Object.defineProperty(props, "hidden", {value: "hidden", enumerable: false})
+  assertEquals(o, Object.defineProperties(o, props))
+  assertEquals("last", key)
+  assertEquals(2, Object.getOwnPropertyNames(desc).length)
+  assertEquals(21, desc.value)
+  assertEquals(true, desc.configurable)
+  assertEquals(undefined, desc.mine)  // Arguably a bug in the spec...
 }

 TestDefine({
@@ -221,6 +289,44 @@



+// Property descriptors (Object.getOwnPropertyDescriptor).
+
+function TestDescriptor(handler) {
+  var o = Proxy.create(handler)
+  var descs = [
+    {configurable: true},
+    {value: 34, enumerable: true, configurable: true},
+    {value: 3, writable: false, mine: "eyes", configurable: true},
+    {get value() { return 20 }, get configurable() { return true }},
+ {get: function() { "get" }, set: function() { "set" }, configurable: true}
+  ]
+  for (var i = 0; i < descs.length; ++i) {
+    assertEquals(o, Object.defineProperty(o, i, descs[i]))
+    var desc = Object.getOwnPropertyDescriptor(o, i)
+    for (p in descs[i]) {
+      // TODO(rossberg): Ignore user attributes as long as the spec isn't
+      // fixed suitably.
+      if (p != "mine") assertEquals(descs[i][p], desc[p])
+    }
+    assertEquals(undefined, Object.getOwnPropertyDescriptor(o, "absent"))
+  }
+}
+
+
+TestDescriptor({
+  defineProperty: function(k, d) { this["__" + k] = d; return true },
+  getOwnPropertyDescriptor: function(k) { return this["__" + k] }
+})
+TestDescriptor({
+  defineProperty: function(k, d) { this["__" + k] = d; return true },
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) { return this["__" + k] }
+})
+
+
+
 // Comparison.

 function TestComparison(eq) {

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

Reply via email to