Bug 1038545 - Coerce the argument passed to Object.keys using ToObject and simplify implementation. r=till
authorziyunfei <446240525@qq.com>
Sun, 05 Oct 2014 00:44:00 +0200
changeset 232130 347f87932c7710393de237caf627fb56f6759040
parent 232129 90f8728118e8ba7018cf9e80bf2f739ce64d0575
child 232131 de956d0e0c46c4c1eec29be075c7f4d55d2e7d7d
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1038545
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1038545 - Coerce the argument passed to Object.keys using ToObject and simplify implementation. r=till
js/src/builtin/Object.cpp
js/src/tests/ecma_6/Object/keys.js
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -834,58 +834,22 @@ js::obj_getOwnPropertyDescriptor(JSConte
     if (!GetFirstArgumentAsObject(cx, args, "Object.getOwnPropertyDescriptor", &obj))
         return false;
     RootedId id(cx);
     if (!ValueToId<CanGC>(cx, args.get(1), &id))
         return false;
     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 */
 static bool
 obj_is(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Object/keys.js
@@ -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);