Bug 645416, part 28 - Update Object.prototype.toSource for symbol-keyed properties. r=Waldo.
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 23 Jun 2014 10:57:03 -0500
changeset 190295 adc814d90d4d16b83d65034b0f3487f173816452
parent 190294 dfefe211d083191c0ca99f865958d0839cbdc31e
child 190296 cd2894ed2c761f525ea5af03525773728e86ef94
push id27004
push useremorley@mozilla.com
push dateTue, 24 Jun 2014 15:52:34 +0000
treeherdermozilla-central@7b174d47f3cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs645416, 924688
milestone33.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 645416, part 28 - Update Object.prototype.toSource for symbol-keyed properties. r=Waldo. The new output uses syntax with square brackets: {[Symbol.for("key")]: "value"} This syntax is not yet supported in SpiderMonkey, but it is part of ES6 (see bug 924688 or search the ES6 drafts for ComputedPropertyName).
js/src/builtin/Object.cpp
js/src/tests/js1_8_5/extensions/object-toSource-with-symbol-keys.js
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -203,37 +203,41 @@ js::ObjectToSource(JSContext *cx, Handle
             if (doGet) {
                 valcnt = 1;
                 gsop[0].set(nullptr);
                 if (!JSObject::getGeneric(cx, obj, obj, id, val[0]))
                     return nullptr;
             }
         }
 
-        /* Convert id to a linear string. */
-        RootedValue idv(cx, IdToValue(id));
-        JSString *s = ToString<CanGC>(cx, idv);
-        if (!s)
-            return nullptr;
-
-        RootedLinearString idstr(cx, s->ensureLinear(cx));
-        if (!idstr)
-            return nullptr;
+        /* Convert id to a string. */
+        RootedString idstr(cx);
+        if (JSID_IS_SYMBOL(id)) {
+            RootedValue v(cx, SymbolValue(JSID_TO_SYMBOL(id)));
+            idstr = ValueToSource(cx, v);
+            if (!idstr)
+                return nullptr;
+        } else {
+            RootedValue idv(cx, IdToValue(id));
+            idstr = ToString<CanGC>(cx, idv);
+            if (!idstr)
+                return nullptr;
 
-        /*
-         * If id is a string that's not an identifier, or if it's a negative
-         * integer, then it must be quoted.
-         */
-        if (JSID_IS_ATOM(id)
-            ? !IsIdentifier(idstr)
-            : (!JSID_IS_INT(id) || JSID_TO_INT(id) < 0))
-        {
-            s = js_QuoteString(cx, idstr, jschar('\''));
-            if (!s || !(idstr = s->ensureLinear(cx)))
-                return nullptr;
+            /*
+             * If id is a string that's not an identifier, or if it's a negative
+             * integer, then it must be quoted.
+             */
+            if (JSID_IS_ATOM(id)
+                ? !IsIdentifier(JSID_TO_ATOM(id))
+                : JSID_TO_INT(id) < 0)
+            {
+                idstr = js_QuoteString(cx, idstr, jschar('\''));
+                if (!idstr)
+                    return nullptr;
+            }
         }
 
         for (int j = 0; j < valcnt; j++) {
             /*
              * Censor an accessor descriptor getter or setter part if it's
              * undefined.
              */
             if (gsop[j] && val[j].isUndefined())
@@ -268,19 +272,23 @@ js::ObjectToSource(JSContext *cx, Handle
 
             if (comma && !buf.append(", "))
                 return nullptr;
             comma = true;
 
             if (gsop[j]) {
                 if (!buf.append(gsop[j]) || !buf.append(' '))
                     return nullptr;
-            }
+            } 
+            if (JSID_IS_SYMBOL(id) && !buf.append('['))
+                return nullptr;
             if (!buf.append(idstr))
                 return nullptr;
+            if (JSID_IS_SYMBOL(id) && !buf.append(']'))
+                return nullptr;
             if (!buf.append(gsop[j] ? ' ' : ':'))
                 return nullptr;
 
             if (!buf.appendSubstring(valstr, voffset, vlength))
                 return nullptr;
         }
     }
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/js1_8_5/extensions/object-toSource-with-symbol-keys.js
@@ -0,0 +1,14 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var obj = {};
+obj[Symbol.iterator] = 1;
+assertEq(obj.toSource(), "({[Symbol.iterator]:1})");
+obj[Symbol(undefined)] = 2;
+obj[Symbol('ponies')] = 3;
+obj[Symbol.for('ponies')] = 4;
+assertEq(obj.toSource(),
+         '({[Symbol.iterator]:1, [Symbol()]:2, [Symbol("ponies")]:3, [Symbol.for("ponies")]:4})');
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);