author | Jason Orendorff <jorendorff@mozilla.com> |
Mon, 23 Jun 2014 10:56:51 -0500 | |
changeset 190283 | db9d35e7c4fd4665c7f508239bb4e0103561a866 |
parent 190282 | 4ad5047763c05acfd90ce97c0d07ad6380f15efe |
child 190284 | 1870f6bc071b1a8cbc1386c6534aa2b81316df16 |
push id | 27004 |
push user | [email protected] |
push date | Tue, 24 Jun 2014 15:52:34 +0000 |
treeherder | mozilla-central@7b174d47f3cc [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sfink |
bugs | 645416 |
milestone | 33.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
|
--- a/js/src/builtin/SymbolObject.cpp +++ b/js/src/builtin/SymbolObject.cpp @@ -39,16 +39,17 @@ SymbolObject::create(JSContext *cx, JS:: } const JSPropertySpec SymbolObject::properties[] = { JS_PS_END }; 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_FS_END }; @@ -178,13 +179,34 @@ SymbolObject::toString_impl(JSContext *c bool SymbolObject::toString(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<IsSymbol, toString_impl>(cx, args); } +//ES6 rev 24 (2014 Apr 27) 19.4.3.3 +bool +SymbolObject::valueOf_impl(JSContext *cx, CallArgs args) +{ + // Step 3, the error case, is handled by CallNonGenericMethod. + HandleValue thisv = args.thisv(); + MOZ_ASSERT(IsSymbol(thisv)); + if (thisv.isSymbol()) + args.rval().set(thisv); + else + args.rval().setSymbol(thisv.toObject().as<SymbolObject>().unbox()); + return true; +} + +bool +SymbolObject::valueOf(JSContext *cx, unsigned argc, Value *vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + return CallNonGenericMethod<IsSymbol, valueOf_impl>(cx, args); +} + JSObject * js_InitSymbolClass(JSContext *cx, HandleObject obj) { return SymbolObject::initClass(cx, obj); }
--- a/js/src/builtin/SymbolObject.h +++ b/js/src/builtin/SymbolObject.h @@ -43,16 +43,18 @@ class SymbolObject : public JSObject static bool construct(JSContext *cx, unsigned argc, Value *vp); // Static methods. static bool for_(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[]; static const JSFunctionSpec methods[]; static const JSFunctionSpec staticMethods[]; }; } /* namespace js */
--- a/js/src/tests/ecma_6/Symbol/as-base-value.js +++ b/js/src/tests/ecma_6/Symbol/as-base-value.js @@ -17,38 +17,41 @@ var symbols = [ // Test accessor property, used below. var gets, sets; Object.defineProperty(Symbol.prototype, "prop", { get: function () { "use strict"; gets++; assertEq(typeof this, "object"); assertEq(this instanceof Symbol, true); + assertEq(this.valueOf(), sym); return "got"; }, set: function (v) { "use strict"; sets++; assertEq(typeof this, "object"); assertEq(this instanceof Symbol, true); + assertEq(this.valueOf(), sym); assertEq(v, "newvalue"); } }); for (var sym of symbols) { assertEq(sym.constructor, Symbol); // method on Object.prototype assertEq(sym.hasOwnProperty("constructor"), false); assertEq(sym.toLocaleString(), sym.toString()); // once .toString() exists // custom method monkeypatched onto Symbol.prototype Symbol.prototype.nonStrictMethod = function (arg) { assertEq(arg, "ok"); assertEq(this instanceof Symbol, true); + assertEq(this.valueOf(), sym); return 13; }; assertEq(sym.nonStrictMethod("ok"), 13); // the same, but strict mode Symbol.prototype.strictMethod = function (arg) { "use strict"; assertEq(arg, "ok2");
--- a/js/src/tests/ecma_6/Symbol/constructor.js +++ b/js/src/tests/ecma_6/Symbol/constructor.js @@ -21,10 +21,13 @@ var obj = { return "ponies"; } }; assertEq(Symbol(obj).toString(), "Symbol(ponies)"); assertEq(hits, 1); assertEq(Object.getPrototypeOf(Symbol.prototype), Object.prototype); +// Symbol.prototype is not itself a Symbol object. +assertThrowsInstanceOf(() => Symbol.prototype.valueOf(), TypeError); + if (typeof reportCompare === "function") reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/surfaces.js +++ b/js/src/tests/ecma_6/Symbol/surfaces.js @@ -18,11 +18,12 @@ assertEq(desc.writable, false); assertEq(Symbol.prototype.constructor, Symbol); desc = Object.getOwnPropertyDescriptor(Symbol.prototype, "constructor"); assertEq(desc.configurable, true); assertEq(desc.enumerable, false); assertEq(desc.writable, true); assertEq(Symbol.for.length, 1); assertEq(Symbol.prototype.toString.length, 0); +assertEq(Symbol.prototype.valueOf.length, 0); if (typeof reportCompare === "function") reportCompare(0, 0);
new file mode 100644 --- /dev/null +++ b/js/src/tests/ecma_6/Symbol/valueOf.js @@ -0,0 +1,22 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ */ + +var symbols = [ + Symbol(), + Symbol("ok"), + Symbol.for("dummies"), + Symbol.iterator +]; + +for (var sym of symbols) { + assertEq(sym.valueOf(), sym); + assertEq(Object(sym).valueOf(), sym); +} + +// Any other value throws. +var nonsymbols = [undefined, null, NaN, {}, Symbol.prototype]; +for (var nonsym of nonsymbols) + assertThrowsInstanceOf(() => Symbol.prototype.valueOf.call(nonsym), TypeError); + +if (typeof reportCompare === "function") + reportCompare(0, 0);