зеркало из https://github.com/mozilla/gecko-dev.git
Bug 700169 - Refactor code to use StringBuffer. r=Waldo
--HG-- extra : rebase_source : fefe9dcae3b2e227b9b32a17a976320eb9d71ba3
This commit is contained in:
Родитель
0042c62308
Коммит
947564fc46
|
@ -0,0 +1,9 @@
|
|||
var errorToString = Error.prototype.toString;
|
||||
|
||||
|
||||
assertEq(errorToString.call({message: "", name: ""}), "Error");
|
||||
assertEq(errorToString.call({name: undefined, message: ""}), "Error");
|
||||
assertEq(errorToString.call({name: "Test", message: undefined}), "Test");
|
||||
assertEq(errorToString.call({name: "Test", message: ""}), "Test");
|
||||
assertEq(errorToString.call({name: "", message: "Test"}), "Test");
|
||||
assertEq(errorToString.call({name: "Test", message: "it!"}), "Test: it!");
|
|
@ -76,8 +76,6 @@ Class js::BooleanClass = {
|
|||
};
|
||||
|
||||
#if JS_HAS_TOSOURCE
|
||||
#include "jsprf.h"
|
||||
|
||||
static JSBool
|
||||
bool_toSource(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
|
@ -87,9 +85,11 @@ bool_toSource(JSContext *cx, uintN argc, Value *vp)
|
|||
if (!BoxedPrimitiveMethodGuard(cx, args, bool_toSource, &b, &ok))
|
||||
return ok;
|
||||
|
||||
char buf[32];
|
||||
JS_snprintf(buf, sizeof buf, "(new Boolean(%s))", JS_BOOLEAN_STR(b));
|
||||
JSString *str = JS_NewStringCopyZ(cx, buf);
|
||||
StringBuffer sb(cx);
|
||||
if (!sb.append("(new Boolean(") || !BooleanToStringBuffer(cx, b, sb) || !sb.append("))"))
|
||||
return false;
|
||||
|
||||
JSString *str = sb.finishString();
|
||||
if (!str)
|
||||
return false;
|
||||
args.rval().setString(str);
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
|
||||
#include "jsinferinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsstrinlines.h"
|
||||
|
||||
#include "vm/Stack-inl.h"
|
||||
|
||||
|
@ -2455,9 +2456,6 @@ date_toDateString(JSContext *cx, uintN argc, Value *vp)
|
|||
}
|
||||
|
||||
#if JS_HAS_TOSOURCE
|
||||
#include <string.h>
|
||||
#include "jsnum.h"
|
||||
|
||||
static JSBool
|
||||
date_toSource(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
|
@ -2468,23 +2466,14 @@ date_toSource(JSContext *cx, uintN argc, Value *vp)
|
|||
if (!obj)
|
||||
return ok;
|
||||
|
||||
double utctime = obj->getDateUTCTime().toNumber();
|
||||
|
||||
ToCStringBuf cbuf;
|
||||
char *numStr = NumberToCString(cx, &cbuf, utctime);
|
||||
if (!numStr) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
StringBuffer sb(cx);
|
||||
if (!sb.append("(new Date(") || !NumberValueToStringBuffer(cx, obj->getDateUTCTime(), sb) ||
|
||||
!sb.append("))"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char *bytes = JS_smprintf("(new %s(%s))", js_Date_str, numStr);
|
||||
if (!bytes) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
JSString *str = JS_NewStringCopyZ(cx, bytes);
|
||||
cx->free_(bytes);
|
||||
JSString *str = sb.finishString();
|
||||
if (!str)
|
||||
return false;
|
||||
args.rval().setString(str);
|
||||
|
|
296
js/src/jsexn.cpp
296
js/src/jsexn.cpp
|
@ -776,68 +776,79 @@ Exception(JSContext *cx, uintN argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert to string.
|
||||
*
|
||||
* This method only uses JavaScript-modifiable properties name, message. It
|
||||
* is left to the host to check for private data and report filename and line
|
||||
* number information along with this message.
|
||||
*/
|
||||
/* ES5 15.11.4.4 (NB: with subsequent errata). */
|
||||
static JSBool
|
||||
exn_toString(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
jsval v;
|
||||
JSString *name, *message, *result;
|
||||
jschar *chars, *cp;
|
||||
size_t name_length, message_length, length;
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
JSObject *obj = ToObject(cx, &vp[1]);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
if (!obj->getProperty(cx, cx->runtime->atomState.nameAtom, &v))
|
||||
return JS_FALSE;
|
||||
name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;
|
||||
vp->setString(name);
|
||||
|
||||
if (!JS_GetProperty(cx, obj, js_message_str, &v))
|
||||
return JS_FALSE;
|
||||
message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v)
|
||||
: cx->runtime->emptyString;
|
||||
|
||||
if (message->length() != 0) {
|
||||
name_length = name->length();
|
||||
message_length = message->length();
|
||||
length = (name_length ? name_length + 2 : 0) + message_length;
|
||||
cp = chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
|
||||
if (!chars)
|
||||
return JS_FALSE;
|
||||
|
||||
if (name_length) {
|
||||
const jschar *name_chars = name->getChars(cx);
|
||||
if (!name_chars)
|
||||
return JS_FALSE;
|
||||
js_strncpy(cp, name_chars, name_length);
|
||||
cp += name_length;
|
||||
*cp++ = ':'; *cp++ = ' ';
|
||||
}
|
||||
const jschar *message_chars = message->getChars(cx);
|
||||
if (!message_chars)
|
||||
return JS_FALSE;
|
||||
js_strncpy(cp, message_chars, message_length);
|
||||
cp += message_length;
|
||||
*cp = 0;
|
||||
|
||||
result = js_NewString(cx, chars, length);
|
||||
if (!result) {
|
||||
cx->free_(chars);
|
||||
return JS_FALSE;
|
||||
}
|
||||
} else {
|
||||
result = name;
|
||||
/* Step 2. */
|
||||
if (!args.thisv().isObject()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE, "Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
vp->setString(result);
|
||||
return JS_TRUE;
|
||||
/* Step 1. */
|
||||
JSObject &obj = args.thisv().toObject();
|
||||
|
||||
/* Step 3. */
|
||||
Value nameVal;
|
||||
if (!obj.getProperty(cx, cx->runtime->atomState.nameAtom, &nameVal))
|
||||
return false;
|
||||
|
||||
/* Step 4. */
|
||||
JSString *name;
|
||||
if (nameVal.isUndefined()) {
|
||||
name = CLASS_ATOM(cx, Error);
|
||||
} else {
|
||||
name = js_ValueToString(cx, nameVal);
|
||||
if (!name)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Step 5. */
|
||||
Value msgVal;
|
||||
if (!obj.getProperty(cx, cx->runtime->atomState.messageAtom, &msgVal))
|
||||
return false;
|
||||
|
||||
/* Step 6. */
|
||||
JSString *message;
|
||||
if (msgVal.isUndefined()) {
|
||||
message = cx->runtime->emptyString;
|
||||
} else {
|
||||
message = js_ValueToString(cx, msgVal);
|
||||
if (!message)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Step 7. */
|
||||
if (name->empty() && message->empty()) {
|
||||
args.rval().setString(CLASS_ATOM(cx, Error));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Step 8. */
|
||||
if (name->empty()) {
|
||||
args.rval().setString(message);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Step 9. */
|
||||
if (message->empty()) {
|
||||
args.rval().setString(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Step 10. */
|
||||
StringBuffer sb(cx);
|
||||
if (!sb.append(name) || !sb.append(": ") || !sb.append(message))
|
||||
return false;
|
||||
|
||||
JSString *str = sb.finishString();
|
||||
if (!str)
|
||||
return false;
|
||||
args.rval().setString(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if JS_HAS_TOSOURCE
|
||||
|
@ -847,134 +858,75 @@ exn_toString(JSContext *cx, uintN argc, Value *vp)
|
|||
static JSBool
|
||||
exn_toSource(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
JSString *name, *message, *filename, *lineno_as_str, *result;
|
||||
jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL};
|
||||
size_t lineno_length, name_length, message_length, filename_length, length;
|
||||
jschar *chars, *cp;
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
JSObject *obj = ToObject(cx, &vp[1]);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
if (!obj->getProperty(cx, cx->runtime->atomState.nameAtom, vp))
|
||||
return false;
|
||||
name = js_ValueToString(cx, *vp);
|
||||
|
||||
JSString *name = js_ValueToString(cx, *vp);
|
||||
if (!name)
|
||||
return false;
|
||||
vp->setString(name);
|
||||
|
||||
Value messageVal;
|
||||
JSString *message;
|
||||
if (!obj->getProperty(cx, cx->runtime->atomState.messageAtom, &messageVal) ||
|
||||
!(message = js_ValueToSource(cx, messageVal)))
|
||||
{
|
||||
AutoArrayRooter tvr(cx, ArrayLength(localroots), localroots);
|
||||
|
||||
#ifdef __GNUC__
|
||||
message = filename = NULL;
|
||||
#endif
|
||||
if (!JS_GetProperty(cx, obj, js_message_str, &localroots[0]) ||
|
||||
!(message = js_ValueToSource(cx, localroots[0]))) {
|
||||
return false;
|
||||
}
|
||||
localroots[0] = STRING_TO_JSVAL(message);
|
||||
|
||||
if (!JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) ||
|
||||
!(filename = js_ValueToSource(cx, localroots[1]))) {
|
||||
return false;
|
||||
}
|
||||
localroots[1] = STRING_TO_JSVAL(filename);
|
||||
|
||||
if (!JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]))
|
||||
return false;
|
||||
uint32_t lineno;
|
||||
if (!ValueToECMAUint32(cx, localroots[2], &lineno))
|
||||
return false;
|
||||
|
||||
if (lineno != 0) {
|
||||
lineno_as_str = js_ValueToString(cx, localroots[2]);
|
||||
if (!lineno_as_str)
|
||||
return false;
|
||||
lineno_length = lineno_as_str->length();
|
||||
} else {
|
||||
lineno_as_str = NULL;
|
||||
lineno_length = 0;
|
||||
}
|
||||
|
||||
/* Magic 8, for the characters in ``(new ())''. */
|
||||
name_length = name->length();
|
||||
message_length = message->length();
|
||||
length = 8 + name_length + message_length;
|
||||
|
||||
filename_length = filename->length();
|
||||
if (filename_length != 0) {
|
||||
/* append filename as ``, {filename}'' */
|
||||
length += 2 + filename_length;
|
||||
if (lineno_as_str) {
|
||||
/* append lineno as ``, {lineno_as_str}'' */
|
||||
length += 2 + lineno_length;
|
||||
}
|
||||
} else {
|
||||
if (lineno_as_str) {
|
||||
/*
|
||||
* no filename, but have line number,
|
||||
* need to append ``, "", {lineno_as_str}''
|
||||
*/
|
||||
length += 6 + lineno_length;
|
||||
}
|
||||
}
|
||||
|
||||
cp = chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
|
||||
if (!chars)
|
||||
return false;
|
||||
|
||||
*cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' ';
|
||||
const jschar *name_chars = name->getChars(cx);
|
||||
if (!name_chars)
|
||||
return false;
|
||||
js_strncpy(cp, name_chars, name_length);
|
||||
cp += name_length;
|
||||
*cp++ = '(';
|
||||
const jschar *message_chars = message->getChars(cx);
|
||||
if (!message_chars)
|
||||
return false;
|
||||
if (message_length != 0) {
|
||||
js_strncpy(cp, message_chars, message_length);
|
||||
cp += message_length;
|
||||
}
|
||||
|
||||
if (filename_length != 0) {
|
||||
/* append filename as ``, {filename}'' */
|
||||
*cp++ = ','; *cp++ = ' ';
|
||||
const jschar *filename_chars = filename->getChars(cx);
|
||||
if (!filename_chars)
|
||||
return false;
|
||||
js_strncpy(cp, filename_chars, filename_length);
|
||||
cp += filename_length;
|
||||
} else {
|
||||
if (lineno_as_str) {
|
||||
/*
|
||||
* no filename, but have line number,
|
||||
* need to append ``, "", {lineno_as_str}''
|
||||
*/
|
||||
*cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"';
|
||||
}
|
||||
}
|
||||
if (lineno_as_str) {
|
||||
/* append lineno as ``, {lineno_as_str}'' */
|
||||
*cp++ = ','; *cp++ = ' ';
|
||||
const jschar *lineno_chars = lineno_as_str->getChars(cx);
|
||||
if (!lineno_chars)
|
||||
return false;
|
||||
js_strncpy(cp, lineno_chars, lineno_length);
|
||||
cp += lineno_length;
|
||||
}
|
||||
|
||||
*cp++ = ')'; *cp++ = ')'; *cp = 0;
|
||||
|
||||
result = js_NewString(cx, chars, length);
|
||||
if (!result) {
|
||||
cx->free_(chars);
|
||||
return false;
|
||||
}
|
||||
vp->setString(result);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Value filenameVal;
|
||||
JSString *filename;
|
||||
if (!obj->getProperty(cx, cx->runtime->atomState.fileNameAtom, &filenameVal) ||
|
||||
!(filename = js_ValueToSource(cx, filenameVal)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Value linenoVal;
|
||||
uint32_t lineno;
|
||||
if (!obj->getProperty(cx, cx->runtime->atomState.lineNumberAtom, &linenoVal) ||
|
||||
!ValueToECMAUint32(cx, linenoVal, &lineno))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
StringBuffer sb(cx);
|
||||
if (!sb.append("(new ") || !sb.append(name) || !sb.append("("))
|
||||
return false;
|
||||
|
||||
if (!sb.append(message))
|
||||
return false;
|
||||
|
||||
if (!filename->empty()) {
|
||||
if (!sb.append(", ") || !sb.append(filename))
|
||||
return false;
|
||||
}
|
||||
if (lineno != 0) {
|
||||
/* We have a line, but no filename, add empty string */
|
||||
if (filename->empty() && !sb.append(", \"\""))
|
||||
return false;
|
||||
|
||||
JSString *linenumber = js_ValueToString(cx, linenoVal);
|
||||
if (!linenumber)
|
||||
return false;
|
||||
if (!sb.append(", ") || !sb.append(linenumber))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sb.append("))"))
|
||||
return false;
|
||||
|
||||
JSString *str = sb.finishString();
|
||||
if (!str)
|
||||
return false;
|
||||
vp->setString(str);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -533,16 +533,14 @@ num_toSource(JSContext *cx, uintN argc, Value *vp)
|
|||
if (!BoxedPrimitiveMethodGuard(cx, args, num_toSource, &d, &ok))
|
||||
return ok;
|
||||
|
||||
ToCStringBuf cbuf;
|
||||
char *numStr = NumberToCString(cx, &cbuf, d);
|
||||
if (!numStr) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
StringBuffer sb(cx);
|
||||
if (!sb.append("(new Number(") || !NumberValueToStringBuffer(cx, NumberValue(d), sb) ||
|
||||
!sb.append("))"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char buf[64];
|
||||
JS_snprintf(buf, sizeof buf, "(new %s(%s))", NumberClass.name, numStr);
|
||||
JSString *str = js_NewStringCopyZ(cx, buf);
|
||||
JSString *str = sb.finishString();
|
||||
if (!str)
|
||||
return false;
|
||||
args.rval().setString(str);
|
||||
|
|
|
@ -85,9 +85,10 @@
|
|||
|
||||
#include "jsarrayinlines.h"
|
||||
#include "jsinterpinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsscopeinlines.h"
|
||||
#include "jsscriptinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsstrinlines.h"
|
||||
|
||||
#include "vm/BooleanObject-inl.h"
|
||||
#include "vm/NumberObject-inl.h"
|
||||
|
@ -843,25 +844,14 @@ obj_toStringHelper(JSContext *cx, JSObject *obj)
|
|||
if (obj->isProxy())
|
||||
return Proxy::obj_toString(cx, obj);
|
||||
|
||||
const char *clazz = obj->getClass()->name;
|
||||
size_t nchars = 9 + strlen(clazz); /* 9 for "[object ]" */
|
||||
jschar *chars = (jschar *) cx->malloc_((nchars + 1) * sizeof(jschar));
|
||||
if (!chars)
|
||||
StringBuffer sb(cx);
|
||||
const char *className = obj->getClass()->name;
|
||||
if (!sb.append("[object ") || !sb.appendInflated(className, strlen(className)) ||
|
||||
!sb.append("]"))
|
||||
{
|
||||
return NULL;
|
||||
|
||||
const char *prefix = "[object ";
|
||||
nchars = 0;
|
||||
while ((chars[nchars] = (jschar)*prefix) != 0)
|
||||
nchars++, prefix++;
|
||||
while ((chars[nchars] = (jschar)*clazz) != 0)
|
||||
nchars++, clazz++;
|
||||
chars[nchars++] = ']';
|
||||
chars[nchars] = 0;
|
||||
|
||||
JSString *str = js_NewString(cx, chars, nchars);
|
||||
if (!str)
|
||||
cx->free_(chars);
|
||||
return str;
|
||||
}
|
||||
return sb.finishString();
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
|
|
@ -470,34 +470,13 @@ str_toSource(JSContext *cx, uintN argc, Value *vp)
|
|||
if (!str)
|
||||
return false;
|
||||
|
||||
char buf[16];
|
||||
size_t j = JS_snprintf(buf, sizeof buf, "(new String(");
|
||||
|
||||
JS::Anchor<JSString *> anchor(str);
|
||||
size_t k = str->length();
|
||||
const jschar *s = str->getChars(cx);
|
||||
if (!s)
|
||||
StringBuffer sb(cx);
|
||||
if (!sb.append("(new String(") || !sb.append(str) || !sb.append("))"))
|
||||
return false;
|
||||
|
||||
size_t n = j + k + 2;
|
||||
jschar *t = (jschar *) cx->malloc_((n + 1) * sizeof(jschar));
|
||||
if (!t)
|
||||
str = sb.finishString();
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < j; i++)
|
||||
t[i] = buf[i];
|
||||
for (j = 0; j < k; i++, j++)
|
||||
t[i] = s[j];
|
||||
t[i++] = ')';
|
||||
t[i++] = ')';
|
||||
t[i] = 0;
|
||||
|
||||
str = js_NewString(cx, t, n);
|
||||
if (!str) {
|
||||
cx->free_(t);
|
||||
return false;
|
||||
}
|
||||
args.rval().setString(str);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@ function test()
|
|||
|
||||
expectExitCode(0);
|
||||
expectExitCode(3);
|
||||
|
||||
actual = 0;
|
||||
|
||||
// construct string of 1<<23 characters
|
||||
|
|
Загрузка…
Ссылка в новой задаче