Bug 1038545 - Coerce the argument passed to Object.keys using ToObject and simplify implementation. r=till

This commit is contained in:
ziyunfei 2014-10-05 00:44:00 +02:00
parent ca093ea6f6
commit 1e24a79fa2
2 changed files with 25 additions and 38 deletions

View File

@ -839,48 +839,12 @@ js::obj_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, Value *vp)
return GetOwnPropertyDescriptor(cx, obj, id, args.rval());
}
// ES6 draft rev25 (2014/05/22) 19.1.2.14 Object.keys(O)
// ES6 draft rev27 (2014/08/24) 19.1.2.14 Object.keys(O)
static bool
obj_keys(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
// Steps 1-2.
RootedObject obj(cx);
if (!GetFirstArgumentAsObject(cx, args, "Object.keys", &obj))
return false;
// Steps 3-10. Since JSITER_SYMBOLS and JSITER_HIDDEN are not passed,
// GetPropertyNames performs the type check in step 10.c. and the
// [[Enumerable]] check specified in step 10.c.iii.
AutoIdVector props(cx);
if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, &props))
return false;
AutoValueVector namelist(cx);
if (!namelist.reserve(props.length()))
return false;
for (size_t i = 0, len = props.length(); i < len; i++) {
jsid id = props[i];
JSString *str;
if (JSID_IS_STRING(id)) {
str = JSID_TO_STRING(id);
} else {
str = Int32ToString<CanGC>(cx, JSID_TO_INT(id));
if (!str)
return false;
}
namelist.infallibleAppend(StringValue(str));
}
// Step 11.
MOZ_ASSERT(props.length() <= UINT32_MAX);
JSObject *aobj = NewDenseCopiedArray(cx, uint32_t(namelist.length()), namelist.begin());
if (!aobj)
return false;
args.rval().setObject(*aobj);
return true;
return GetOwnPropertyKeys(cx, args, JSITER_OWNONLY);
}
/* ES6 draft 15.2.3.16 */

View File

@ -0,0 +1,23 @@
/*
* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/
*/
var BUGNUMBER = 1038545;
var summary = "Coerce the argument passed to Object.keys using ToObject";
print(BUGNUMBER + ": " + summary);
assertThrowsInstanceOf(() => Object.keys(), TypeError);
assertThrowsInstanceOf(() => Object.keys(undefined), TypeError);
assertThrowsInstanceOf(() => Object.keys(null), TypeError);
assertDeepEq(Object.keys(1), []);
assertDeepEq(Object.keys(true), []);
if (typeof Symbol === "function") {
assertDeepEq(Object.keys(Symbol("foo")), []);
}
assertDeepEq(Object.keys("foo"), ["0", "1", "2"]);
if (typeof reportCompare === "function")
reportCompare(true, true);