Bug 575522 - Object.prototype.toString should return "[object Undefined]" and "[object Null]" when called with |this === undefined| or |this === null|, respectively. r=jorendorff,brendan

This commit is contained in:
Jeff Walden 2010-10-12 11:50:03 -07:00
parent 4626f47ec6
commit 0b9b58415c
5 changed files with 71 additions and 5 deletions

View File

@ -158,6 +158,8 @@ const char *const js_common_atom_names[] = {
js_name_str, /* nameAtom */
js_next_str, /* nextAtom */
js_noSuchMethod_str, /* noSuchMethodAtom */
"[object Null]", /* objectNullAtom */
"[object Undefined]", /* objectUndefinedAtom */
js_proto_str, /* protoAtom */
js_set_str, /* setAtom */
js_source_str, /* sourceAtom */

View File

@ -351,6 +351,8 @@ struct JSAtomState
JSAtom *nameAtom;
JSAtom *nextAtom;
JSAtom *noSuchMethodAtom;
JSAtom *objectNullAtom;
JSAtom *objectUndefinedAtom;
JSAtom *protoAtom;
JSAtom *setAtom;
JSAtom *sourceAtom;

View File

@ -835,17 +835,32 @@ obj_toStringHelper(JSContext *cx, JSObject *obj)
}
/* ES5 15.2.4.2. Note steps 1 and 2 are errata. */
static JSBool
obj_toString(JSContext *cx, uintN argc, Value *vp)
{
JSObject *obj = ComputeThisFromVp(cx, vp);
if (!obj)
Value &thisv = vp[1];
/* ES5 15.2.4.2 step 1. */
if (thisv.isUndefined()) {
vp->setString(ATOM_TO_STRING(cx->runtime->atomState.objectUndefinedAtom));
return true;
}
/* ES5 15.2.4.2 step 2. */
if (thisv.isNull()) {
vp->setString(ATOM_TO_STRING(cx->runtime->atomState.objectNullAtom));
return true;
}
/* ES5 15.2.4.2 step 3. */
if (!thisv.isObject() && !js_PrimitiveToObject(cx, &thisv))
return false;
JSString *str = js::obj_toStringHelper(cx, obj);
/* ES5 15.2.4.2 steps 4-5. */
JSString *str = js::obj_toStringHelper(cx, &thisv.toObject());
if (!str)
return false;
vp->setString(str);
return true;
}
@ -2692,7 +2707,7 @@ static JSFunctionSpec object_methods[] = {
#if JS_HAS_TOSOURCE
JS_FN(js_toSource_str, obj_toSource, 0,0),
#endif
JS_FN(js_toString_str, obj_toString, 0,0),
JS_FN(js_toString_str, obj_toString, 0,JSFUN_PRIMITIVE_THIS),
JS_FN(js_toLocaleString_str, obj_toLocaleString, 0,0),
JS_FN(js_valueOf_str, obj_valueOf, 0,0),
#if JS_HAS_OBJ_WATCHPOINT

View File

@ -37,4 +37,5 @@ skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-7-of-8.js # u
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-8-of-8.js # uses shell load() function
script 15.2.3.6-define-over-method.js
script mutation-prevention-methods.js
script object-toString-01.js
script vacuous-accessor-unqualified-name.js

View File

@ -0,0 +1,46 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
* Contributor:
* Jeff Walden <jwalden+code@mit.edu>
*/
var gTestfile = 'object-toString-01.js';
//-----------------------------------------------------------------------------
var BUGNUMBER = 575522;
var summary = '({}).toString.call(null) == "[object Null]", ' +
'({}).toString.call(undefined) == "[object Undefined]", ';
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
var toString = Object.prototype.toString;
assertEq(toString.call(null), "[object Null]");
assertEq(toString.call(undefined), "[object Undefined]");
assertEq(toString.call(true), "[object Boolean]");
assertEq(toString.call(false), "[object Boolean]");
assertEq(toString.call(0), "[object Number]");
assertEq(toString.call(-0), "[object Number]");
assertEq(toString.call(1), "[object Number]");
assertEq(toString.call(-1), "[object Number]");
assertEq(toString.call(NaN), "[object Number]");
assertEq(toString.call(Infinity), "[object Number]");
assertEq(toString.call(-Infinity), "[object Number]");
assertEq(toString.call("foopy"), "[object String]");
assertEq(toString.call({}), "[object Object]");
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("All tests passed!");