Bug 645416, part 29 - Implement Symbol.keyFor(). r=efaust.
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 23 Jun 2014 10:57:04 -0500
changeset 190296 cd2894ed2c761f525ea5af03525773728e86ef94
parent 190295 adc814d90d4d16b83d65034b0f3487f173816452
child 190297 8672d6f14537a99ec8d557060a087257df3657c5
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)
reviewersefaust
bugs645416
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 29 - Implement Symbol.keyFor(). r=efaust.
js/src/builtin/SymbolObject.cpp
js/src/builtin/SymbolObject.h
js/src/tests/ecma_6/Symbol/keyFor.js
--- a/js/src/builtin/SymbolObject.cpp
+++ b/js/src/builtin/SymbolObject.cpp
@@ -45,16 +45,17 @@ const JSPropertySpec SymbolObject::prope
 const JSFunctionSpec SymbolObject::methods[] = {
     JS_FN(js_toString_str, toString, 0, 0),
     JS_FN(js_valueOf_str, valueOf, 0, 0),
     JS_FS_END
 };
 
 const JSFunctionSpec SymbolObject::staticMethods[] = {
     JS_FN("for", for_, 1, 0),
+    JS_FN("keyFor", keyFor, 1, 0),
     JS_FS_END
 };
 
 JSObject *
 SymbolObject::initClass(JSContext *cx, HandleObject obj)
 {
     Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
 
@@ -143,16 +144,46 @@ SymbolObject::for_(JSContext *cx, unsign
     // steps 3-7
     JS::Symbol *symbol = JS::Symbol::for_(cx, stringKey);
     if (!symbol)
         return false;
     args.rval().setSymbol(symbol);
     return true;
 }
 
+// ES6 rev 25 (2014 May 22) 19.4.2.7
+bool
+SymbolObject::keyFor(JSContext *cx, unsigned argc, Value *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    // step 1
+    HandleValue arg = args.get(0);
+    if (!arg.isSymbol()) {
+        js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK,
+                                 arg, js::NullPtr(), "not a symbol", nullptr);
+        return false;
+    }
+
+    // step 2
+    if (arg.toSymbol()->code() == JS::SymbolCode::InSymbolRegistry) {
+#ifdef DEBUG
+        RootedString desc(cx, arg.toSymbol()->description());
+        MOZ_ASSERT(Symbol::for_(cx, desc) == arg.toSymbol());
+#endif
+        args.rval().setString(arg.toSymbol()->description());
+        return true;
+    }
+
+    // step 3: omitted
+    // step 4
+    args.rval().setUndefined();
+    return true;
+}
+
 MOZ_ALWAYS_INLINE bool
 IsSymbol(HandleValue v)
 {
     return v.isSymbol() || (v.isObject() && v.toObject().is<SymbolObject>());
 }
 
 //ES6 rev 24 (2014 Apr 27) 19.4.3.2
 bool
--- a/js/src/builtin/SymbolObject.h
+++ b/js/src/builtin/SymbolObject.h
@@ -41,16 +41,17 @@ class SymbolObject : public JSObject
     }
 
     static bool construct(JSContext *cx, unsigned argc, Value *vp);
 
     static bool convert(JSContext *cx, HandleObject obj, JSType type, MutableHandleValue vp);
 
     // Static methods.
     static bool for_(JSContext *cx, unsigned argc, Value *vp);
+    static bool keyFor(JSContext *cx, unsigned argc, Value *vp);
 
     // Methods defined on Symbol.prototype.
     static bool toString_impl(JSContext *cx, CallArgs args);
     static bool toString(JSContext *cx, unsigned argc, Value *vp);
     static bool valueOf_impl(JSContext *cx, CallArgs args);
     static bool valueOf(JSContext *cx, unsigned argc, Value *vp);
 
     static const JSPropertySpec properties[];
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/keyFor.js
@@ -0,0 +1,15 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+assertEq(Symbol.keyFor(Symbol.for("moon")), "moon");
+assertEq(Symbol.keyFor(Symbol.for("")), "");
+assertEq(Symbol.keyFor(Symbol("moon")), undefined);
+assertEq(Symbol.keyFor(Symbol.iterator), undefined);
+
+assertThrowsInstanceOf(() => Symbol.keyFor(), TypeError);
+assertThrowsInstanceOf(() => Symbol.keyFor(Object(Symbol("moon"))), TypeError);
+
+assertEq(Symbol.keyFor.length, 1);
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);