Commit 6e2da733 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Implement Object.keys for proxies.

R=kmillikin@chromium.org,ager@chromium.org
BUG=
TEST=

Review URL: http://codereview.chromium.org/7321004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e4f7860a
......@@ -135,3 +135,15 @@ function DerivedSetTrap(receiver, name, val) {
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
}
......@@ -308,6 +308,13 @@ function ObjectLookupSetter(name) {
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 @@ function GetProperty(obj, p) {
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 @@ function HasProperty(obj, p) {
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 @@ function DefineProxyProperty(obj, p, attributes, should_throw) {
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 @@ function ObjectGetOwnPropertyNames(obj) {
throw MakeTypeError("handler_trap_missing",
[handler, "getOwnPropertyNames"]);
}
var names = getOwnPropertyNames.call(handler);
var names = %_CallFunction(handler, getOwnPropertyNames);
return ToStringArray(names, "getOwnPropertyNames");
}
......
......@@ -309,7 +309,7 @@ TestPrototype()
// Property names (Object.getOwnPropertyNames).
// Property names (Object.getOwnPropertyNames, Object.keys).
function TestPropertyNames(names, handler) {
var p = Proxy.create(handler)
......@@ -331,3 +331,51 @@ TestPropertyNames(["[object Object]"], {
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 {} }
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment