author | Jeff Walden <jwalden@mit.edu> |
Tue, 11 Jan 2011 16:29:09 -0600 | |
changeset 60558 | 039f81de26e57580d52004ad7203f246cabd24d6 |
parent 60557 | 39bac86bb16810fa727a514f3ec34e93530c31ce |
child 60559 | 18e064a4bb68b6de1337a25ee13b98e9940a967c |
push id | 18037 |
push user | cleary@mozilla.com |
push date | Fri, 14 Jan 2011 17:42:55 +0000 |
treeherder | mozilla-central@4e0501a0c5e5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | the |
milestone | 2.0b9pre |
backs out | 567f16dd81f377718d0a948c150b3b8331fb64e5 |
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
|
js/src/jsnum.cpp | file | annotate | diff | comparison | revisions | |
js/src/json.cpp | file | annotate | diff | comparison | revisions | |
js/src/jsstr.cpp | file | annotate | diff | comparison | revisions | |
js/src/tests/ecma_5/JSON/jstests.list | file | annotate | diff | comparison | revisions | |
js/src/tests/ecma_5/JSON/stringify-boxed-primitives.js | file | annotate | diff | comparison | revisions |
--- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -939,16 +939,17 @@ JS_DEFINE_TRCINFO_2(num_toString, static JSFunctionSpec number_methods[] = { #if JS_HAS_TOSOURCE JS_FN(js_toSource_str, num_toSource, 0, 0), #endif JS_TN(js_toString_str, num_toString, 1, 0, &num_toString_trcinfo), JS_FN(js_toLocaleString_str, num_toLocaleString, 0, 0), JS_FN(js_valueOf_str, js_num_valueOf, 0, 0), + JS_FN(js_toJSON_str, js_num_valueOf, 0, 0), JS_FN("toFixed", num_toFixed, 1, 0), JS_FN("toExponential", num_toExponential, 1, 0), JS_FN("toPrecision", num_toPrecision, 1, 0), JS_FS_END }; /* NB: Keep this in synch with number_constants[]. */ enum nc_slot {
--- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -485,104 +485,79 @@ CallReplacerFunction(JSContext *cx, jsid 2, Jsvalify(vec), Jsvalify(vp))) { return JS_FALSE; } } return JS_TRUE; } -/* ES5 15.12.3 Str. */ static JSBool Str(JSContext *cx, jsid id, JSObject *holder, StringifyContext *scx, Value *vp, bool callReplacer) { - JS_CHECK_RECURSION(cx, return false); + JS_CHECK_RECURSION(cx, return JS_FALSE); - /* - * This method implements the Str algorithm in ES5 15.12.3, but we move - * property retrieval into the caller to stream the stringification process - * and avoid constantly copying strings. - */ + if (vp->isObject() && !js_TryJSON(cx, vp)) + return JS_FALSE; - /* Step 2. */ - if (vp->isObject() && !js_TryJSON(cx, vp)) - return false; + if (callReplacer && !CallReplacerFunction(cx, id, holder, scx, vp)) + return JS_FALSE; - /* Step 3. */ - if (callReplacer && !CallReplacerFunction(cx, id, holder, scx, vp)) - return false; - - /* Step 4. */ + // catches string and number objects with no toJSON if (vp->isObject()) { JSObject *obj = &vp->toObject(); Class *clasp = obj->getClass(); - if (clasp == &js_NumberClass) { - double d; - if (!ValueToNumber(cx, *vp, &d)) - return false; - vp->setNumber(d); - } else if (clasp == &js_StringClass) { - JSString *str = js_ValueToString(cx, *vp); - if (!str) - return false; - vp->setString(str); - } else if (clasp == &js_BooleanClass) { + if (clasp == &js_StringClass || clasp == &js_NumberClass) *vp = obj->getPrimitiveThis(); - } } - /* Step 8. */ if (vp->isString()) { JSString *str = vp->toString(); size_t length = str->length(); const jschar *chars = str->getChars(cx); if (!chars) - return false; + return JS_FALSE; return write_string(cx, scx->cb, chars, length); } - /* Step 5. */ - if (vp->isNull()) + if (vp->isNull()) { return js_AppendLiteral(scx->cb, "null"); + } - /* Steps 6-7. */ if (vp->isBoolean()) { return vp->toBoolean() ? js_AppendLiteral(scx->cb, "true") : js_AppendLiteral(scx->cb, "false"); } - /* Step 9. */ if (vp->isNumber()) { if (vp->isDouble()) { jsdouble d = vp->toDouble(); if (!JSDOUBLE_IS_FINITE(d)) return js_AppendLiteral(scx->cb, "null"); } JSCharBuffer cb(cx); if (!js_NumberValueToCharBuffer(cx, *vp, cb)) - return false; + return JS_FALSE; return scx->cb.append(cb.begin(), cb.length()); } - /* Step 10. */ if (vp->isObject() && !IsFunctionObject(*vp) && !IsXML(*vp)) { JSBool ok; scx->depth++; ok = (JS_IsArrayObject(cx, &vp->toObject()) ? JA : JO)(cx, vp, scx); scx->depth--; return ok; } - /* Step 11. */ vp->setUndefined(); - return true; + return JS_TRUE; } JSBool js_Stringify(JSContext *cx, Value *vp, JSObject *replacer, const Value &space, JSCharBuffer &cb) { StringifyContext scx(cx, cb, replacer); if (!scx.initializeGap(cx, space) || !scx.initializeStack())
--- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -3057,16 +3057,17 @@ static JSFunctionSpec string_methods[] = #if JS_HAS_TOSOURCE JS_FN("quote", str_quote, 0,JSFUN_GENERIC_NATIVE), JS_FN(js_toSource_str, str_toSource, 0,0), #endif /* Java-like methods. */ JS_FN(js_toString_str, js_str_toString, 0,0), JS_FN(js_valueOf_str, js_str_toString, 0,0), + JS_FN(js_toJSON_str, js_str_toString, 0,0), JS_FN("substring", str_substring, 2,JSFUN_GENERIC_NATIVE), JS_FN("toLowerCase", str_toLowerCase, 0,JSFUN_GENERIC_NATIVE), JS_FN("toUpperCase", str_toUpperCase, 0,JSFUN_GENERIC_NATIVE), JS_FN("charAt", js_str_charAt, 1,JSFUN_GENERIC_NATIVE), JS_FN("charCodeAt", js_str_charCodeAt, 1,JSFUN_GENERIC_NATIVE), JS_FN("indexOf", str_indexOf, 1,JSFUN_GENERIC_NATIVE), JS_FN("lastIndexOf", str_lastIndexOf, 1,JSFUN_GENERIC_NATIVE), JS_FN("trim", str_trim, 0,JSFUN_GENERIC_NATIVE),
--- a/js/src/tests/ecma_5/JSON/jstests.list +++ b/js/src/tests/ecma_5/JSON/jstests.list @@ -1,6 +1,5 @@ url-prefix ../../jsreftest.html?test=ecma_5/JSON/ script cyclic-stringify.js script small-codepoints.js script trailing-comma.js script stringify-gap.js -script stringify-boxed-primitives.js
deleted file mode 100644 --- a/js/src/tests/ecma_5/JSON/stringify-boxed-primitives.js +++ /dev/null @@ -1,127 +0,0 @@ -// Any copyright is dedicated to the Public Domain. -// http://creativecommons.org/licenses/publicdomain/ - -var gTestfile = 'stringify-boxed-primitives.js'; -//----------------------------------------------------------------------------- -var BUGNUMBER = 584909; -var summary = "Stringification of Boolean/String/Number objects"; - -print(BUGNUMBER + ": " + summary); - -/************** - * BEGIN TEST * - **************/ - -function redefine(obj, prop, fun) -{ - var desc = - { value: fun, writable: true, configurable: true, enumerable: false }; - Object.defineProperty(obj, prop, desc); -} - -assertEq(JSON.stringify(new Boolean(false)), "false"); - -assertEq(JSON.stringify(new Number(5)), "5"); - -assertEq(JSON.stringify(new String("foopy")), '"foopy"'); - - -var numToString = Number.prototype.toString; -var numValueOf = Number.prototype.valueOf; -var objToString = Object.prototype.toString; -var objValueOf = Object.prototype.valueOf; -var boolToString = Boolean.prototype.toString; -var boolValueOf = Boolean.prototype.valueOf; - -redefine(Boolean.prototype, "toString", function() { return 17; }); -assertEq(JSON.stringify(new Boolean(false)), "false") -delete Boolean.prototype.toString; -assertEq(JSON.stringify(new Boolean(false)), "false"); -delete Object.prototype.toString; -assertEq(JSON.stringify(new Boolean(false)), "false"); -delete Boolean.prototype.valueOf; -assertEq(JSON.stringify(new Boolean(false)), "false"); -delete Object.prototype.valueOf; -assertEq(JSON.stringify(new Boolean(false)), "false"); - - -redefine(Boolean.prototype, "toString", boolToString); -redefine(Boolean.prototype, "valueOf", boolValueOf); -redefine(Object.prototype, "toString", objToString); -redefine(Object.prototype, "valueOf", objValueOf); - -redefine(Number.prototype, "toString", function() { return 42; }); -assertEq(JSON.stringify(new Number(5)), "5"); -redefine(Number.prototype, "valueOf", function() { return 17; }); -assertEq(JSON.stringify(new Number(5)), "17"); -delete Number.prototype.toString; -assertEq(JSON.stringify(new Number(5)), "17"); -delete Number.prototype.valueOf; -assertEq(JSON.stringify(new Number(5)), "null"); // isNaN(Number("[object Number]")) -delete Object.prototype.toString; -try -{ - JSON.stringify(new Number(5)); - throw new Error("didn't throw"); -} -catch (e) -{ - assertEq(e instanceof TypeError, true, - "ToNumber failure, should throw TypeError"); -} -delete Object.prototype.valueOf; -try -{ - JSON.stringify(new Number(5)); - throw new Error("didn't throw"); -} -catch (e) -{ - assertEq(e instanceof TypeError, true, - "ToNumber failure, should throw TypeError"); -} - - -redefine(Number.prototype, "toString", numToString); -redefine(Number.prototype, "valueOf", numValueOf); -redefine(Object.prototype, "toString", objToString); -redefine(Object.prototype, "valueOf", objValueOf); - - -redefine(String.prototype, "valueOf", function() { return 17; }); -assertEq(JSON.stringify(new String(5)), '"5"'); -redefine(String.prototype, "toString", function() { return 42; }); -assertEq(JSON.stringify(new String(5)), '"42"'); -delete String.prototype.toString; -assertEq(JSON.stringify(new String(5)), '"[object String]"'); -delete Object.prototype.toString; -assertEq(JSON.stringify(new String(5)), '"17"'); -delete String.prototype.valueOf; -try -{ - JSON.stringify(new String(5)); - throw new Error("didn't throw"); -} -catch (e) -{ - assertEq(e instanceof TypeError, true, - "ToString failure, should throw TypeError"); -} -delete Object.prototype.valueOf; -try -{ - JSON.stringify(new String(5)); - throw new Error("didn't throw"); -} -catch (e) -{ - assertEq(e instanceof TypeError, true, - "ToString failure, should throw TypeError"); -} - -/******************************************************************************/ - -if (typeof reportCompare === "function") - reportCompare(true, true); - -print("All tests passed!");