Bug 707061 - Rename js_ValueToString to ToString. Also, consistent with ToObject, make ToString include an inline already-string fast path, and make ToStringSlow be an out-of-line slow path for the case where the value is not a string (asserting that this is the case). r=luke

This commit is contained in:
Jeff Walden 2011-12-01 19:35:44 -08:00
Родитель c1aa143b02
Коммит 863c0fe811
22 изменённых файлов: 113 добавлений и 108 удалений

Просмотреть файл

@ -256,7 +256,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder,
sourceStr = cx->runtime->emptyString; sourceStr = cx->runtime->emptyString;
} else { } else {
/* Coerce to string and compile. */ /* Coerce to string and compile. */
JSString *str = js_ValueToString(cx, sourceValue); JSString *str = ToString(cx, sourceValue);
if (!str) if (!str)
return false; return false;
sourceStr = str->ensureLinear(cx); sourceStr = str->ensureLinear(cx);
@ -266,7 +266,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder,
RegExpFlag flags = RegExpFlag(0); RegExpFlag flags = RegExpFlag(0);
if (argc > 1 && !argv[1].isUndefined()) { if (argc > 1 && !argv[1].isUndefined()) {
JSString *flagStr = js_ValueToString(cx, argv[1]); JSString *flagStr = ToString(cx, argv[1]);
if (!flagStr) if (!flagStr)
return false; return false;
argv[1].setString(flagStr); argv[1].setString(flagStr);
@ -528,7 +528,7 @@ ExecuteRegExp(JSContext *cx, Native native, uintN argc, Value *vp)
RegExpStatics *res = cx->regExpStatics(); RegExpStatics *res = cx->regExpStatics();
/* Step 2. */ /* Step 2. */
JSString *input = js_ValueToString(cx, (args.length() > 0) ? args[0] : UndefinedValue()); JSString *input = ToString(cx, (args.length() > 0) ? args[0] : UndefinedValue());
if (!input) if (!input)
return false; return false;

Просмотреть файл

@ -316,7 +316,7 @@ JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv, const char *format
break; break;
case 'S': case 'S':
case 'W': case 'W':
str = js_ValueToString(cx, *sp); str = ToString(cx, *sp);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*sp = STRING_TO_JSVAL(str); *sp = STRING_TO_JSVAL(str);
@ -433,7 +433,7 @@ JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
ok = (obj != NULL); ok = (obj != NULL);
break; break;
case JSTYPE_STRING: case JSTYPE_STRING:
str = js_ValueToString(cx, v); str = ToString(cx, v);
ok = (str != NULL); ok = (str != NULL);
if (ok) if (ok)
*vp = STRING_TO_JSVAL(str); *vp = STRING_TO_JSVAL(str);
@ -486,7 +486,7 @@ JS_ValueToString(JSContext *cx, jsval v)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, v); assertSameCompartment(cx, v);
return js_ValueToString(cx, v); return ToString(cx, v);
} }
JS_PUBLIC_API(JSString *) JS_PUBLIC_API(JSString *)

Просмотреть файл

@ -1870,7 +1870,7 @@ array_join(JSContext *cx, uintN argc, Value *vp)
if (args.length() == 0 || args[0].isUndefined()) { if (args.length() == 0 || args[0].isUndefined()) {
str = NULL; str = NULL;
} else { } else {
str = js_ValueToString(cx, args[0]); str = ToString(cx, args[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
args[0].setString(str); args[0].setString(str);
@ -2177,7 +2177,7 @@ js::array_sort(JSContext *cx, uintN argc, Value *vp)
if (!JS_CHECK_OPERATION_LIMIT(cx)) if (!JS_CHECK_OPERATION_LIMIT(cx))
return false; return false;
const Value &v = vec[i]; const Value &v = vec[i];
JSString *str = js_ValueToString(cx, v); JSString *str = ToString(cx, v);
if (!str) if (!str)
return false; return false;

Просмотреть файл

@ -51,7 +51,7 @@ inline bool
js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp) js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
{ {
if (!v.isString()) { if (!v.isString()) {
JSString *str = js_ValueToString(cx, v); JSString *str = js::ToStringSlow(cx, v);
if (!str) if (!str)
return false; return false;
JS::Anchor<JSString *> anchor(str); JS::Anchor<JSString *> anchor(str);
@ -184,7 +184,7 @@ IdToString(JSContext *cx, jsid id)
return JSID_TO_STRING(id); return JSID_TO_STRING(id);
if (JS_LIKELY(JSID_IS_INT(id))) if (JS_LIKELY(JSID_IS_INT(id)))
return js_IntToString(cx, JSID_TO_INT(id)); return js_IntToString(cx, JSID_TO_INT(id));
return js_ValueToString(cx, IdToValue(id)); return js::ToStringSlow(cx, IdToValue(id));
} }
} // namespace js } // namespace js

Просмотреть файл

@ -1190,7 +1190,7 @@ date_parse(JSContext *cx, uintN argc, Value *vp)
vp->setDouble(js_NaN); vp->setDouble(js_NaN);
return true; return true;
} }
str = js_ValueToString(cx, vp[2]); str = ToString(cx, vp[2]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
vp[2].setString(str); vp[2].setString(str);
@ -2417,7 +2417,7 @@ date_toLocaleFormat(JSContext *cx, uintN argc, Value *vp)
if (!obj) if (!obj)
return ok; return ok;
JSString *fmt = js_ValueToString(cx, args[0]); JSString *fmt = ToString(cx, args[0]);
if (!fmt) if (!fmt)
return false; return false;
@ -2511,7 +2511,7 @@ date_valueOf(JSContext *cx, uintN argc, Value *vp)
} }
/* Convert to number only if the hint was given, otherwise favor string. */ /* Convert to number only if the hint was given, otherwise favor string. */
JSString *str = js_ValueToString(cx, args[0]); JSString *str = ToString(cx, args[0]);
if (!str) if (!str)
return false; return false;
JSLinearString *linear_str = str->ensureLinear(cx); JSLinearString *linear_str = str->ensureLinear(cx);
@ -2606,7 +2606,7 @@ js_Date(JSContext *cx, uintN argc, Value *vp)
d = TIMECLIP(d); d = TIMECLIP(d);
} else { } else {
/* the argument is a string; parse it. */ /* the argument is a string; parse it. */
JSString *str = js_ValueToString(cx, args[0]); JSString *str = ToString(cx, args[0]);
if (!str) if (!str)
return false; return false;
args[0].setString(str); args[0].setString(str);

Просмотреть файл

@ -729,7 +729,7 @@ Exception(JSContext *cx, uintN argc, Value *vp)
/* Set the 'message' property. */ /* Set the 'message' property. */
JSString *message; JSString *message;
if (args.length() != 0 && !args[0].isUndefined()) { if (args.length() != 0 && !args[0].isUndefined()) {
message = js_ValueToString(cx, args[0]); message = ToString(cx, args[0]);
if (!message) if (!message)
return false; return false;
args[0].setString(message); args[0].setString(message);
@ -745,7 +745,7 @@ Exception(JSContext *cx, uintN argc, Value *vp)
/* Set the 'fileName' property. */ /* Set the 'fileName' property. */
JSString *filename; JSString *filename;
if (args.length() > 1) { if (args.length() > 1) {
filename = js_ValueToString(cx, args[1]); filename = ToString(cx, args[1]);
if (!filename) if (!filename)
return false; return false;
args[1].setString(filename); args[1].setString(filename);
@ -801,7 +801,7 @@ exn_toString(JSContext *cx, uintN argc, Value *vp)
if (nameVal.isUndefined()) { if (nameVal.isUndefined()) {
name = CLASS_ATOM(cx, Error); name = CLASS_ATOM(cx, Error);
} else { } else {
name = js_ValueToString(cx, nameVal); name = ToString(cx, nameVal);
if (!name) if (!name)
return false; return false;
} }
@ -816,7 +816,7 @@ exn_toString(JSContext *cx, uintN argc, Value *vp)
if (msgVal.isUndefined()) { if (msgVal.isUndefined()) {
message = cx->runtime->emptyString; message = cx->runtime->emptyString;
} else { } else {
message = js_ValueToString(cx, msgVal); message = ToString(cx, msgVal);
if (!message) if (!message)
return false; return false;
} }
@ -867,7 +867,8 @@ exn_toSource(JSContext *cx, uintN argc, Value *vp)
Value nameVal; Value nameVal;
JSString *name; JSString *name;
if (!obj->getProperty(cx, cx->runtime->atomState.nameAtom, &nameVal) || if (!obj->getProperty(cx, cx->runtime->atomState.nameAtom, &nameVal) ||
!(name = js_ValueToString(cx, nameVal))) { !(name = ToString(cx, nameVal)))
{
return false; return false;
} }
@ -911,7 +912,7 @@ exn_toSource(JSContext *cx, uintN argc, Value *vp)
if (filename->empty() && !sb.append(", \"\"")) if (filename->empty() && !sb.append(", \"\""))
return false; return false;
JSString *linenumber = js_ValueToString(cx, linenoVal); JSString *linenumber = ToString(cx, linenoVal);
if (!linenumber) if (!linenumber)
return false; return false;
if (!sb.append(", ") || !sb.append(linenumber)) if (!sb.append(", ") || !sb.append(linenumber))
@ -1178,10 +1179,10 @@ js_ReportUncaughtException(JSContext *cx)
AutoArrayRooter tvr(cx, ArrayLength(roots), roots); AutoArrayRooter tvr(cx, ArrayLength(roots), roots);
/* /*
* Because js_ValueToString below could error and an exception object * Because ToString below could error and an exception object could become
* could become unrooted, we must root exnObject. Later, if exnObject is * unrooted, we must root exnObject. Later, if exnObject is non-null, we
* non-null, we need to root other intermediates, so allocate an operand * need to root other intermediates, so allocate an operand stack segment
* stack segment to protect all of these values. * to protect all of these values.
*/ */
if (JSVAL_IS_PRIMITIVE(exn)) { if (JSVAL_IS_PRIMITIVE(exn)) {
exnObject = NULL; exnObject = NULL;
@ -1194,12 +1195,12 @@ js_ReportUncaughtException(JSContext *cx)
reportp = js_ErrorFromException(cx, exn); reportp = js_ErrorFromException(cx, exn);
/* XXX L10N angels cry once again. see also everywhere else */ /* XXX L10N angels cry once again. see also everywhere else */
str = js_ValueToString(cx, exn); str = ToString(cx, exn);
JSAutoByteString bytesStorage; JSAutoByteString bytesStorage;
if (!str) { if (!str) {
bytes = "unknown (can't convert to string)"; bytes = "unknown (can't convert to string)";
} else { } else {
roots[1] = STRING_TO_JSVAL(str); roots[1] = StringValue(str);
if (!bytesStorage.encode(cx, str)) if (!bytesStorage.encode(cx, str))
return false; return false;
bytes = bytesStorage.ptr(); bytes = bytesStorage.ptr();
@ -1218,7 +1219,7 @@ js_ReportUncaughtException(JSContext *cx)
if (!JS_GetProperty(cx, exnObject, js_fileName_str, &roots[3])) if (!JS_GetProperty(cx, exnObject, js_fileName_str, &roots[3]))
return false; return false;
str = js_ValueToString(cx, roots[3]); str = ToString(cx, roots[3]);
if (!str || !filename.encode(cx, str)) if (!str || !filename.encode(cx, str))
return false; return false;

Просмотреть файл

@ -1976,7 +1976,7 @@ Function(JSContext *cx, uintN argc, Value *vp)
size_t args_length = 0; size_t args_length = 0;
for (uintN i = 0; i < n; i++) { for (uintN i = 0; i < n; i++) {
/* Collect the lengths for all the function-argument arguments. */ /* Collect the lengths for all the function-argument arguments. */
JSString *arg = js_ValueToString(cx, args[i]); JSString *arg = ToString(cx, args[i]);
if (!arg) if (!arg)
return false; return false;
args[i].setString(arg); args[i].setString(arg);
@ -2084,7 +2084,7 @@ Function(JSContext *cx, uintN argc, Value *vp)
size_t length; size_t length;
if (args.length()) { if (args.length()) {
JSString *str = js_ValueToString(cx, args[args.length() - 1]); JSString *str = ToString(cx, args[args.length() - 1]);
if (!str) if (!str)
return false; return false;
strAnchor.set(str); strAnchor.set(str);

Просмотреть файл

@ -2685,7 +2685,7 @@ BEGIN_CASE(JSOP_ADD)
if (lIsString) { if (lIsString) {
lstr = lval.toString(); lstr = lval.toString();
} else { } else {
lstr = js_ValueToString(cx, lval); lstr = ToString(cx, lval);
if (!lstr) if (!lstr)
goto error; goto error;
regs.sp[-2].setString(lstr); regs.sp[-2].setString(lstr);
@ -2693,7 +2693,7 @@ BEGIN_CASE(JSOP_ADD)
if (rIsString) { if (rIsString) {
rstr = rval.toString(); rstr = rval.toString();
} else { } else {
rstr = js_ValueToString(cx, rval); rstr = ToString(cx, rval);
if (!rstr) if (!rstr)
goto error; goto error;
regs.sp[-1].setString(rstr); regs.sp[-1].setString(rstr);
@ -5124,7 +5124,7 @@ BEGIN_CASE(JSOP_XMLTAGEXPR)
JS_ASSERT(!script->strictModeCode); JS_ASSERT(!script->strictModeCode);
Value rval = regs.sp[-1]; Value rval = regs.sp[-1];
JSString *str = js_ValueToString(cx, rval); JSString *str = ToString(cx, rval);
if (!str) if (!str)
goto error; goto error;
regs.sp[-1].setString(str); regs.sp[-1].setString(str);
@ -5140,7 +5140,7 @@ BEGIN_CASE(JSOP_XMLELTEXPR)
if (IsXML(rval)) { if (IsXML(rval)) {
str = js_ValueToXMLString(cx, rval); str = js_ValueToXMLString(cx, rval);
} else { } else {
str = js_ValueToString(cx, rval); str = ToString(cx, rval);
if (str) if (str)
str = js_EscapeElementValue(cx, str); str = js_EscapeElementValue(cx, str);
} }

Просмотреть файл

@ -1053,7 +1053,7 @@ js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
if (rval->isInt32() && StaticStrings::hasInt(i = rval->toInt32())) { if (rval->isInt32() && StaticStrings::hasInt(i = rval->toInt32())) {
str = cx->runtime->staticStrings.getInt(i); str = cx->runtime->staticStrings.getInt(i);
} else { } else {
str = js_ValueToString(cx, *rval); str = ToString(cx, *rval);
if (!str) if (!str)
return false; return false;
} }

Просмотреть файл

@ -321,7 +321,7 @@ num_parseFloat(JSContext *cx, uintN argc, Value *vp)
vp->setDouble(js_NaN); vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
str = js_ValueToString(cx, vp[2]); str = ToString(cx, vp[2]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
bp = str->getChars(cx); bp = str->getChars(cx);
@ -438,7 +438,7 @@ num_parseInt(JSContext *cx, uintN argc, Value *vp)
} }
/* Step 1. */ /* Step 1. */
JSString *inputString = js_ValueToString(cx, args[0]); JSString *inputString = ToString(cx, args[0]);
if (!inputString) if (!inputString)
return false; return false;
args[0].setString(inputString); args[0].setString(inputString);

Просмотреть файл

@ -598,7 +598,7 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
* Convert id to a value and then to a string. Decide early whether we * Convert id to a value and then to a string. Decide early whether we
* prefer get/set or old getter/setter syntax. * prefer get/set or old getter/setter syntax.
*/ */
JSString *s = js_ValueToString(cx, IdToValue(id)); JSString *s = ToString(cx, IdToValue(id));
if (!s || !(idstr = s->ensureLinear(cx))) { if (!s || !(idstr = s->ensureLinear(cx))) {
ok = JS_FALSE; ok = JS_FALSE;
goto error; goto error;
@ -2638,7 +2638,7 @@ obj_getOwnPropertyNames(JSContext *cx, uintN argc, Value *vp)
for (size_t i = 0, len = keys.length(); i < len; i++) { for (size_t i = 0, len = keys.length(); i < len; i++) {
jsid id = keys[i]; jsid id = keys[i];
if (JSID_IS_INT(id)) { if (JSID_IS_INT(id)) {
JSString *str = js_ValueToString(cx, Int32Value(JSID_TO_INT(id))); JSString *str = js_IntToString(cx, JSID_TO_INT(id));
if (!str) if (!str)
return false; return false;
vals[i].setString(str); vals[i].setString(str);

Просмотреть файл

@ -92,7 +92,7 @@ js_json_parse(JSContext *cx, uintN argc, Value *vp)
/* Step 1. */ /* Step 1. */
JSLinearString *linear; JSLinearString *linear;
if (argc >= 1) { if (argc >= 1) {
JSString *str = js_ValueToString(cx, vp[2]); JSString *str = ToString(cx, vp[2]);
if (!str) if (!str)
return false; return false;
linear = str->ensureLinear(cx); linear = str->ensureLinear(cx);
@ -367,7 +367,7 @@ PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, Stringi
return false; return false;
vp->setNumber(d); vp->setNumber(d);
} else if (ObjectClassIs(obj, ESClass_String, cx)) { } else if (ObjectClassIs(obj, ESClass_String, cx)) {
JSString *str = js_ValueToString(cx, *vp); JSString *str = ToStringSlow(cx, *vp);
if (!str) if (!str)
return false; return false;
vp->setString(str); vp->setString(str);
@ -716,7 +716,7 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer, Value space, StringBu
return false; return false;
space = NumberValue(d); space = NumberValue(d);
} else if (ObjectClassIs(spaceObj, ESClass_String, cx)) { } else if (ObjectClassIs(spaceObj, ESClass_String, cx)) {
JSString *str = js_ValueToString(cx, space); JSString *str = ToStringSlow(cx, space);
if (!str) if (!str)
return false; return false;
space = StringValue(str); space = StringValue(str);

Просмотреть файл

@ -1472,7 +1472,7 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
return JS_FALSE; return JS_FALSE;
str = NULL; str = NULL;
} else { } else {
str = js_ValueToString(cx, key); str = ToString(cx, key);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
} }

Просмотреть файл

@ -257,7 +257,7 @@ Shape::dump(JSContext *cx, FILE *fp) const
str = JSID_TO_ATOM(propid); str = JSID_TO_ATOM(propid);
} else { } else {
JS_ASSERT(JSID_IS_OBJECT(propid)); JS_ASSERT(JSID_IS_OBJECT(propid));
JSString *s = js_ValueToString(cx, IdToValue(propid)); JSString *s = ToStringSlow(cx, IdToValue(propid));
fputs("object ", fp); fputs("object ", fp);
str = s ? s->ensureLinear(cx) : NULL; str = s ? s->ensureLinear(cx) : NULL;
} }

Просмотреть файл

@ -404,7 +404,7 @@ Trap(JSContext *cx, JSObject *handler, Value fval, uintN argc, Value* argv, Valu
static bool static bool
Trap1(JSContext *cx, JSObject *handler, Value fval, jsid id, Value *rval) Trap1(JSContext *cx, JSObject *handler, Value fval, jsid id, Value *rval)
{ {
JSString *str = js_ValueToString(cx, IdToValue(id)); JSString *str = ToString(cx, IdToValue(id));
if (!str) if (!str)
return false; return false;
rval->setString(str); rval->setString(str);
@ -414,7 +414,7 @@ Trap1(JSContext *cx, JSObject *handler, Value fval, jsid id, Value *rval)
static bool static bool
Trap2(JSContext *cx, JSObject *handler, Value fval, jsid id, Value v, Value *rval) Trap2(JSContext *cx, JSObject *handler, Value fval, jsid id, Value v, Value *rval)
{ {
JSString *str = js_ValueToString(cx, IdToValue(id)); JSString *str = ToString(cx, IdToValue(id));
if (!str) if (!str)
return false; return false;
rval->setString(str); rval->setString(str);
@ -650,7 +650,7 @@ bool
ScriptedProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp) ScriptedProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp)
{ {
JSObject *handler = GetProxyHandlerObject(cx, proxy); JSObject *handler = GetProxyHandlerObject(cx, proxy);
JSString *str = js_ValueToString(cx, IdToValue(id)); JSString *str = ToString(cx, IdToValue(id));
if (!str) if (!str)
return false; return false;
AutoValueRooter tvr(cx, StringValue(str)); AutoValueRooter tvr(cx, StringValue(str));
@ -668,7 +668,7 @@ ScriptedProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver, js
Value *vp) Value *vp)
{ {
JSObject *handler = GetProxyHandlerObject(cx, proxy); JSObject *handler = GetProxyHandlerObject(cx, proxy);
JSString *str = js_ValueToString(cx, IdToValue(id)); JSString *str = ToString(cx, IdToValue(id));
if (!str) if (!str)
return false; return false;
AutoValueRooter tvr(cx, StringValue(str)); AutoValueRooter tvr(cx, StringValue(str));

Просмотреть файл

@ -3143,7 +3143,7 @@ reflect_parse(JSContext *cx, uint32 argc, jsval *vp)
return JS_FALSE; return JS_FALSE;
} }
JSString *src = js_ValueToString(cx, JS_ARGV(cx, vp)[0]); JSString *src = ToString(cx, JS_ARGV(cx, vp)[0]);
if (!src) if (!src)
return JS_FALSE; return JS_FALSE;
@ -3183,7 +3183,7 @@ reflect_parse(JSContext *cx, uint32 argc, jsval *vp)
} }
if (!prop.isNullOrUndefined()) { if (!prop.isNullOrUndefined()) {
JSString *str = js_ValueToString(cx, prop); JSString *str = ToString(cx, prop);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;

Просмотреть файл

@ -430,7 +430,7 @@ ThisToStringForStringProto(JSContext *cx, Value *vp)
return NULL; return NULL;
} }
JSString *str = js_ValueToString(cx, vp[1]); JSString *str = ToStringSlow(cx, vp[1]);
if (!str) if (!str)
return NULL; return NULL;
vp[1].setString(str); vp[1].setString(str);
@ -679,7 +679,7 @@ str_localeCompare(JSContext *cx, uintN argc, Value *vp)
if (argc == 0) { if (argc == 0) {
vp->setInt32(0); vp->setInt32(0);
} else { } else {
JSString *thatStr = js_ValueToString(cx, vp[2]); JSString *thatStr = ToString(cx, vp[2]);
if (!thatStr) if (!thatStr)
return false; return false;
if (cx->localeCallbacks && cx->localeCallbacks->localeCompare) { if (cx->localeCallbacks && cx->localeCallbacks->localeCompare) {
@ -1401,7 +1401,7 @@ class RegExpGuard
/* Build RegExp from pattern string. */ /* Build RegExp from pattern string. */
JSString *opt; JSString *opt;
if (optarg < argc) { if (optarg < argc) {
opt = js_ValueToString(cx, vp[2 + optarg]); opt = ToString(cx, vp[2 + optarg]);
if (!opt) if (!opt)
return NULL; return NULL;
} else { } else {
@ -1789,7 +1789,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
return false; return false;
/* root repstr: rdata is on the stack, so scanned by conservative gc. */ /* root repstr: rdata is on the stack, so scanned by conservative gc. */
JSString *repstr = ValueToString_TestForStringInline(cx, args.rval()); JSString *repstr = ToString(cx, args.rval());
if (!repstr) if (!repstr)
return false; return false;
rdata.repstr = repstr->ensureLinear(cx); rdata.repstr = repstr->ensureLinear(cx);
@ -2095,7 +2095,7 @@ str_replace_flat_lambda(JSContext *cx, uintN argc, Value *vp, ReplaceData &rdata
if (!Invoke(cx, rdata.args)) if (!Invoke(cx, rdata.args))
return false; return false;
JSString *repstr = js_ValueToString(cx, args.rval()); JSString *repstr = ToString(cx, args.rval());
if (!repstr) if (!repstr)
return false; return false;
@ -2472,7 +2472,7 @@ js::str_split(JSContext *cx, uintN argc, Value *vp)
if (!matcher.reset(reobj)) if (!matcher.reset(reobj))
return false; return false;
} else { } else {
JSString *sep = js_ValueToString(cx, vp[2]); JSString *sep = ToString(cx, vp[2]);
if (!sep) if (!sep)
return false; return false;
vp[2].setString(sep); vp[2].setString(sep);
@ -2587,7 +2587,7 @@ str_concat(JSContext *cx, uintN argc, Value *vp)
Value *argv = JS_ARGV(cx, vp); Value *argv = JS_ARGV(cx, vp);
for (uintN i = 0; i < argc; i++) { for (uintN i = 0; i < argc; i++) {
JSString *str2 = js_ValueToString(cx, argv[i]); JSString *str2 = ToString(cx, argv[i]);
if (!str2) if (!str2)
return false; return false;
@ -2890,7 +2890,7 @@ js_String(JSContext *cx, uintN argc, Value *vp)
JSString *str; JSString *str;
if (argc > 0) { if (argc > 0) {
str = js_ValueToString(cx, argv[0]); str = ToString(cx, argv[0]);
if (!str) if (!str)
return false; return false;
} else { } else {
@ -3218,7 +3218,7 @@ js_ValueToPrintable(JSContext *cx, const Value &v, JSAutoByteString *bytes, bool
{ {
JSString *str; JSString *str;
str = (asSource ? js_ValueToSource : js_ValueToString)(cx, v); str = (asSource ? js_ValueToSource : ToString)(cx, v);
if (!str) if (!str)
return NULL; return NULL;
str = js_QuoteString(cx, str, 0); str = js_QuoteString(cx, str, 0);
@ -3228,8 +3228,11 @@ js_ValueToPrintable(JSContext *cx, const Value &v, JSAutoByteString *bytes, bool
} }
JSString * JSString *
js_ValueToString(JSContext *cx, const Value &arg) js::ToStringSlow(JSContext *cx, const Value &arg)
{ {
/* As with ToObjectSlow, callers must verify that |arg| isn't a string. */
JS_ASSERT(!arg.isString());
Value v = arg; Value v = arg;
if (!ToPrimitive(cx, JSTYPE_STRING, &v)) if (!ToPrimitive(cx, JSTYPE_STRING, &v))
return NULL; return NULL;
@ -3288,7 +3291,7 @@ js_ValueToSource(JSContext *cx, const Value &v)
return js_NewStringCopyN(cx, js_negzero_ucNstr, 2); return js_NewStringCopyN(cx, js_negzero_ucNstr, 2);
} }
return js_ValueToString(cx, v); return ToString(cx, v);
} }
Value rval = NullValue(); Value rval = NullValue();
@ -3301,7 +3304,7 @@ js_ValueToSource(JSContext *cx, const Value &v)
return NULL; return NULL;
} }
return js_ValueToString(cx, rval); return ToString(cx, rval);
} }
namespace js { namespace js {

Просмотреть файл

@ -139,26 +139,26 @@ extern const char *
js_ValueToPrintable(JSContext *cx, const js::Value &, js_ValueToPrintable(JSContext *cx, const js::Value &,
JSAutoByteString *bytes, bool asSource = false); JSAutoByteString *bytes, bool asSource = false);
/*
* Convert a value to a string, returning null after reporting an error,
* otherwise returning a new string reference.
*/
extern JSString *
js_ValueToString(JSContext *cx, const js::Value &v);
namespace js { namespace js {
/* /*
* Most code that calls js_ValueToString knows the value is (probably) not a * Convert a non-string value to a string, returning null after reporting an
* string, so it does not make sense to put this inline fast path into * error, otherwise returning a new string reference.
* js_ValueToString. */
extern JSString *
ToStringSlow(JSContext *cx, const Value &v);
/*
* Convert the given value to a string. This method includes an inline
* fast-path for the case where the value is already a string; if the value is
* known not to be a string, use ToStringSlow instead.
*/ */
static JS_ALWAYS_INLINE JSString * static JS_ALWAYS_INLINE JSString *
ValueToString_TestForStringInline(JSContext *cx, const Value &v) ToString(JSContext *cx, const js::Value &v)
{ {
if (v.isString()) if (v.isString())
return v.toString(); return v.toString();
return js_ValueToString(cx, v); return ToStringSlow(cx, v);
} }
/* /*

Просмотреть файл

@ -585,7 +585,7 @@ js_IsXMLName(JSContext *cx, jsval v)
name = JSVAL_TO_OBJECT(v)->getQNameLocalName(); name = JSVAL_TO_OBJECT(v)->getQNameLocalName();
} else { } else {
older = JS_SetErrorReporter(cx, NULL); older = JS_SetErrorReporter(cx, NULL);
JSString *str = js_ValueToString(cx, v); JSString *str = ToString(cx, v);
if (str) if (str)
name = str->ensureLinear(cx); name = str->ensureLinear(cx);
JS_SetErrorReporter(cx, older); JS_SetErrorReporter(cx, older);
@ -659,7 +659,7 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
obj->setNameURI(uri); obj->setNameURI(uri);
obj->setNamePrefix(uriobj->getNamePrefix()); obj->setNamePrefix(uriobj->getNamePrefix());
} else { } else {
JSString *str = js_ValueToString(cx, urival); JSString *str = ToString(cx, urival);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
uri = str->ensureLinear(cx); uri = str->ensureLinear(cx);
@ -671,7 +671,7 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
} }
} else if (argc == 2) { } else if (argc == 2) {
if (!isQName || !(uri = uriobj->getNameURI())) { if (!isQName || !(uri = uriobj->getNameURI())) {
JSString *str = js_ValueToString(cx, urival); JSString *str = ToString(cx, urival);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
uri = str->ensureLinear(cx); uri = str->ensureLinear(cx);
@ -683,7 +683,7 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
prefixval = argv[0]; prefixval = argv[0];
if (uri->empty()) { if (uri->empty()) {
if (!JSVAL_IS_VOID(prefixval)) { if (!JSVAL_IS_VOID(prefixval)) {
JSString *str = js_ValueToString(cx, prefixval); JSString *str = ToString(cx, prefixval);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
if (!str->empty()) { if (!str->empty()) {
@ -698,7 +698,7 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
} else if (JSVAL_IS_VOID(prefixval) || !js_IsXMLName(cx, prefixval)) { } else if (JSVAL_IS_VOID(prefixval) || !js_IsXMLName(cx, prefixval)) {
obj->clearNamePrefix(); obj->clearNamePrefix();
} else { } else {
JSString *str = js_ValueToString(cx, prefixval); JSString *str = ToString(cx, prefixval);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
prefix = str->ensureLinear(cx); prefix = str->ensureLinear(cx);
@ -821,7 +821,7 @@ QNameHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, jsval *rval)
prefix = obj2->getNamePrefix(); prefix = obj2->getNamePrefix();
} else { } else {
JS_ASSERT(argc > 1); JS_ASSERT(argc > 1);
JSString *str = js_ValueToString(cx, nsval); JSString *str = ToString(cx, nsval);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
uri = str->ensureLinear(cx); uri = str->ensureLinear(cx);
@ -1907,7 +1907,7 @@ ToXML(JSContext *cx, jsval v)
} }
} }
str = js_ValueToString(cx, v); str = ToString(cx, v);
if (!str) if (!str)
return NULL; return NULL;
if (str->empty()) { if (str->empty()) {
@ -1988,7 +1988,7 @@ ToXMLList(JSContext *cx, jsval v)
} }
} }
str = js_ValueToString(cx, v); str = ToString(cx, v);
if (!str) if (!str)
return NULL; return NULL;
if (str->empty()) { if (str->empty()) {
@ -2799,7 +2799,7 @@ ToXMLString(JSContext *cx, jsval v, uint32 toSourceFlag)
} }
if (JSVAL_IS_BOOLEAN(v) || JSVAL_IS_NUMBER(v)) if (JSVAL_IS_BOOLEAN(v) || JSVAL_IS_NUMBER(v))
return js_ValueToString(cx, v); return ToString(cx, v);
if (JSVAL_IS_STRING(v)) { if (JSVAL_IS_STRING(v)) {
StringBuffer sb(cx); StringBuffer sb(cx);
@ -2810,7 +2810,7 @@ ToXMLString(JSContext *cx, jsval v, uint32 toSourceFlag)
if (!obj->isXML()) { if (!obj->isXML()) {
if (!ToPrimitive(cx, JSTYPE_STRING, &v)) if (!ToPrimitive(cx, JSTYPE_STRING, &v))
return NULL; return NULL;
JSString *str = js_ValueToString(cx, v); JSString *str = ToString(cx, v);
if (!str) if (!str)
return NULL; return NULL;
StringBuffer sb(cx); StringBuffer sb(cx);
@ -2934,7 +2934,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
name = cx->runtime->atomState.starAtom; name = cx->runtime->atomState.starAtom;
goto construct; goto construct;
} }
name = js_ValueToString(cx, v); name = ToStringSlow(cx, v);
if (!name) if (!name)
return NULL; return NULL;
} }
@ -3535,7 +3535,7 @@ Insert(JSContext *cx, JSXML *xml, uint32 i, jsval v)
} }
} }
if (!vxml) { if (!vxml) {
str = js_ValueToString(cx, v); str = ToString(cx, v);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
@ -3614,7 +3614,7 @@ Replace(JSContext *cx, JSXML *xml, uint32 i, jsval v)
break; break;
default: default:
str = js_ValueToString(cx, v); str = ToString(cx, v);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
@ -3881,7 +3881,7 @@ KidToString(JSContext *cx, JSXML *xml, uint32 index)
kidobj = js_GetXMLObject(cx, kid); kidobj = js_GetXMLObject(cx, kid);
if (!kidobj) if (!kidobj)
return NULL; return NULL;
return js_ValueToString(cx, ObjectValue(*kidobj)); return ToString(cx, ObjectValue(*kidobj));
} }
/* Forward declared -- its implementation uses other statics that call it. */ /* Forward declared -- its implementation uses other statics that call it. */
@ -5288,8 +5288,8 @@ js_TestXMLEquality(JSContext *cx, const Value &v1, const Value &v2, JSBool *bp)
HasSimpleContent(xml))) { HasSimpleContent(xml))) {
ok = js_EnterLocalRootScope(cx); ok = js_EnterLocalRootScope(cx);
if (ok) { if (ok) {
ok = (str = js_ValueToString(cx, ObjectValue(*obj))) && ok = (str = ToStringSlow(cx, ObjectValue(*obj))) &&
(vstr = js_ValueToString(cx, v)); (vstr = ToString(cx, v));
if (ok) if (ok)
ok = EqualStrings(cx, str, vstr, bp); ok = EqualStrings(cx, str, vstr, bp);
js_LeaveLocalRootScope(cx); js_LeaveLocalRootScope(cx);
@ -5302,12 +5302,12 @@ js_TestXMLEquality(JSContext *cx, const Value &v1, const Value &v2, JSBool *bp)
ok = js_EnterLocalRootScope(cx); ok = js_EnterLocalRootScope(cx);
if (ok) { if (ok) {
if (HasSimpleContent(xml)) { if (HasSimpleContent(xml)) {
ok = (str = js_ValueToString(cx, ObjectValue(*obj))) && ok = (str = ToString(cx, ObjectValue(*obj))) &&
(vstr = js_ValueToString(cx, v)); (vstr = ToString(cx, v));
if (ok) if (ok)
ok = EqualStrings(cx, str, vstr, bp); ok = EqualStrings(cx, str, vstr, bp);
} else if (JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v)) { } else if (JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v)) {
str = js_ValueToString(cx, ObjectValue(*obj)); str = ToString(cx, ObjectValue(*obj));
if (!str) { if (!str) {
ok = JS_FALSE; ok = JS_FALSE;
} else if (JSVAL_IS_STRING(v)) { } else if (JSVAL_IS_STRING(v)) {
@ -6214,7 +6214,7 @@ xml_namespace(JSContext *cx, uintN argc, jsval *vp)
if (argc == 0) { if (argc == 0) {
prefix = NULL; prefix = NULL;
} else { } else {
JSString *str = js_ValueToString(cx, vp[2]); JSString *str = ToString(cx, vp[2]);
if (!str) if (!str)
return false; return false;
prefix = str->ensureLinear(cx); prefix = str->ensureLinear(cx);

Просмотреть файл

@ -983,7 +983,7 @@ stubs::Add(VMFrame &f)
if (lIsString) { if (lIsString) {
lstr = lval.toString(); lstr = lval.toString();
} else { } else {
lstr = js_ValueToString(cx, lval); lstr = ToString(cx, lval);
if (!lstr) if (!lstr)
THROW(); THROW();
regs.sp[-2].setString(lstr); regs.sp[-2].setString(lstr);
@ -991,7 +991,7 @@ stubs::Add(VMFrame &f)
if (rIsString) { if (rIsString) {
rstr = rval.toString(); rstr = rval.toString();
} else { } else {
rstr = js_ValueToString(cx, rval); rstr = ToString(cx, rval);
if (!rstr) if (!rstr)
THROW(); THROW();
regs.sp[-1].setString(rstr); regs.sp[-1].setString(rstr);

Просмотреть файл

@ -245,9 +245,9 @@ ReportException(JSContext *cx)
} }
} }
class ToString { class ToStringHelper {
public: public:
ToString(JSContext *aCx, jsval v, JSBool aThrow = JS_FALSE) ToStringHelper(JSContext *aCx, jsval v, JSBool aThrow = JS_FALSE)
: cx(aCx), mThrow(aThrow) : cx(aCx), mThrow(aThrow)
{ {
mStr = JS_ValueToString(cx, v); mStr = JS_ValueToString(cx, v);
@ -255,7 +255,7 @@ class ToString {
ReportException(cx); ReportException(cx);
JS_AddNamedStringRoot(cx, &mStr, "Value ToString helper"); JS_AddNamedStringRoot(cx, &mStr, "Value ToString helper");
} }
~ToString() { ~ToStringHelper() {
JS_RemoveStringRoot(cx, &mStr); JS_RemoveStringRoot(cx, &mStr);
} }
JSBool threw() { return !mStr; } JSBool threw() { return !mStr; }
@ -272,10 +272,10 @@ class ToString {
JSAutoByteString mBytes; JSAutoByteString mBytes;
}; };
class IdStringifier : public ToString { class IdStringifier : public ToStringHelper {
public: public:
IdStringifier(JSContext *cx, jsid id, JSBool aThrow = JS_FALSE) IdStringifier(JSContext *cx, jsid id, JSBool aThrow = JS_FALSE)
: ToString(cx, IdToJsval(id), aThrow) : ToStringHelper(cx, IdToJsval(id), aThrow)
{ } { }
}; };
@ -2643,8 +2643,8 @@ ConvertArgs(JSContext *cx, uintN argc, jsval *vp)
fprintf(gOutFile, fprintf(gOutFile,
"b %u, c %x (%c), i %ld, u %lu, j %ld\n", "b %u, c %x (%c), i %ld, u %lu, j %ld\n",
b, c, (char)c, i, u, j); b, c, (char)c, i, u, j);
ToString obj2string(cx, obj2); ToStringHelper obj2string(cx, obj2);
ToString valueString(cx, v); ToStringHelper valueString(cx, v);
JSAutoByteString strBytes; JSAutoByteString strBytes;
if (str) if (str)
strBytes.encode(cx, str); strBytes.encode(cx, str);
@ -4357,7 +4357,7 @@ its_addProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
IdStringifier idString(cx, id); IdStringifier idString(cx, id);
fprintf(gOutFile, "adding its property %s,", idString.getBytes()); fprintf(gOutFile, "adding its property %s,", idString.getBytes());
ToString valueString(cx, *vp); ToStringHelper valueString(cx, *vp);
fprintf(gOutFile, " initial value %s\n", valueString.getBytes()); fprintf(gOutFile, " initial value %s\n", valueString.getBytes());
return JS_TRUE; return JS_TRUE;
} }
@ -4370,7 +4370,7 @@ its_delProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
IdStringifier idString(cx, id); IdStringifier idString(cx, id);
fprintf(gOutFile, "deleting its property %s,", idString.getBytes()); fprintf(gOutFile, "deleting its property %s,", idString.getBytes());
ToString valueString(cx, *vp); ToStringHelper valueString(cx, *vp);
fprintf(gOutFile, " initial value %s\n", valueString.getBytes()); fprintf(gOutFile, " initial value %s\n", valueString.getBytes());
return JS_TRUE; return JS_TRUE;
} }
@ -4383,7 +4383,7 @@ its_getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
IdStringifier idString(cx, id); IdStringifier idString(cx, id);
fprintf(gOutFile, "getting its property %s,", idString.getBytes()); fprintf(gOutFile, "getting its property %s,", idString.getBytes());
ToString valueString(cx, *vp); ToStringHelper valueString(cx, *vp);
fprintf(gOutFile, " initial value %s\n", valueString.getBytes()); fprintf(gOutFile, " initial value %s\n", valueString.getBytes());
return JS_TRUE; return JS_TRUE;
} }
@ -4394,7 +4394,7 @@ its_setProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
IdStringifier idString(cx, id); IdStringifier idString(cx, id);
if (its_noisy) { if (its_noisy) {
fprintf(gOutFile, "setting its property %s,", idString.getBytes()); fprintf(gOutFile, "setting its property %s,", idString.getBytes());
ToString valueString(cx, *vp); ToStringHelper valueString(cx, *vp);
fprintf(gOutFile, " new value %s\n", valueString.getBytes()); fprintf(gOutFile, " new value %s\n", valueString.getBytes());
} }
@ -4809,7 +4809,7 @@ env_setProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
IdStringifier idstr(cx, id, JS_TRUE); IdStringifier idstr(cx, id, JS_TRUE);
if (idstr.threw()) if (idstr.threw())
return JS_FALSE; return JS_FALSE;
ToString valstr(cx, *vp, JS_TRUE); ToStringHelper valstr(cx, *vp, JS_TRUE);
if (valstr.threw()) if (valstr.threw())
return JS_FALSE; return JS_FALSE;
#if defined XP_WIN || defined HPUX || defined OSF1 #if defined XP_WIN || defined HPUX || defined OSF1

Просмотреть файл

@ -43,6 +43,7 @@
#include "jsapi.h" #include "jsapi.h"
#include "jscntxt.h" #include "jscntxt.h"
#include "jsgcmark.h" #include "jsgcmark.h"
#include "jsnum.h"
#include "jsobj.h" #include "jsobj.h"
#include "jswrapper.h" #include "jswrapper.h"
#include "jsarrayinlines.h" #include "jsarrayinlines.h"
@ -3116,7 +3117,7 @@ DebuggerObject_getOwnPropertyNames(JSContext *cx, uintN argc, Value *vp)
for (size_t i = 0, len = keys.length(); i < len; i++) { for (size_t i = 0, len = keys.length(); i < len; i++) {
jsid id = keys[i]; jsid id = keys[i];
if (JSID_IS_INT(id)) { if (JSID_IS_INT(id)) {
JSString *str = js_ValueToString(cx, Int32Value(JSID_TO_INT(id))); JSString *str = js_IntToString(cx, JSID_TO_INT(id));
if (!str) if (!str)
return false; return false;
vals[i].setString(str); vals[i].setString(str);