bug 617215 - eliminating JS_NewString usage in FF while fixing a leak there. r=bz a=blocking b8

This commit is contained in:
Igor Bukanov 2010-12-09 11:22:15 +01:00
parent 0664856568
commit 5e5303042f
9 changed files with 44 additions and 50 deletions

View File

@ -10,11 +10,7 @@
static JSBool static JSBool
stringToId(JSContext *cx, const char *s, jsid *idp) stringToId(JSContext *cx, const char *s, jsid *idp)
{ {
char *buf = JS_strdup(cx, s); JSString *str = JS_NewStringCopyZ(cx, s);
if (!buf)
return false;
JSString *str = JS_NewString(cx, buf, strlen(s));
if (!str) if (!str)
return false; return false;

View File

@ -5118,8 +5118,12 @@ JS_NewString(JSContext *cx, char *bytes, size_t nbytes)
/* Free chars (but not bytes, which caller frees on error) if we fail. */ /* Free chars (but not bytes, which caller frees on error) if we fail. */
str = js_NewString(cx, chars, length); str = js_NewString(cx, chars, length);
if (!str) if (!str) {
cx->free(chars); cx->free(chars);
return NULL;
}
js_free(bytes);
return str; return str;
} }

View File

@ -2955,6 +2955,12 @@ class JSAutoByteString {
js_free(mBytes); js_free(mBytes);
} }
/* Take ownership of the given byte array. */
void initBytes(char *bytes) {
JS_ASSERT(!mBytes);
mBytes = bytes;
}
char *encode(JSContext *cx, JSString *str) { char *encode(JSContext *cx, JSString *str) {
JS_ASSERT(!mBytes); JS_ASSERT(!mBytes);
JS_ASSERT(cx); JS_ASSERT(cx);

View File

@ -2355,11 +2355,10 @@ date_toSource(JSContext *cx, uintN argc, Value *vp)
return JS_FALSE; return JS_FALSE;
} }
str = JS_NewString(cx, bytes, strlen(bytes)); str = JS_NewStringCopyZ(cx, bytes);
if (!str) { js_free(bytes);
js_free(bytes); if (!str)
return JS_FALSE; return JS_FALSE;
}
vp->setString(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }

View File

@ -812,11 +812,10 @@ num_toLocaleString(JSContext *cx, uintN argc, Value *vp)
if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode) if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode)
return cx->localeCallbacks->localeToUnicode(cx, buf, Jsvalify(vp)); return cx->localeCallbacks->localeToUnicode(cx, buf, Jsvalify(vp));
str = JS_NewString(cx, buf, size); str = js_NewStringCopyN(cx, buf, size);
if (!str) { cx->free(buf);
cx->free(buf); if (!str)
return JS_FALSE; return JS_FALSE;
}
vp->setString(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;

View File

@ -296,42 +296,43 @@ ToDisassemblySource(JSContext *cx, jsval v, JSAutoByteString *bytes)
if (clasp == &js_BlockClass) { if (clasp == &js_BlockClass) {
char *source = JS_sprintf_append(NULL, "depth %d {", OBJ_BLOCK_DEPTH(cx, obj)); char *source = JS_sprintf_append(NULL, "depth %d {", OBJ_BLOCK_DEPTH(cx, obj));
if (!source)
return false;
Shape::Range r = obj->lastProperty()->all(); Shape::Range r = obj->lastProperty()->all();
while (!r.empty()) { while (!r.empty()) {
const Shape &shape = r.front(); const Shape &shape = r.front();
JSAutoByteString bytes; JSAutoByteString bytes;
if (!js_AtomToPrintableString(cx, JSID_TO_ATOM(shape.id), &bytes)) if (!js_AtomToPrintableString(cx, JSID_TO_ATOM(shape.id), &bytes))
return NULL; return false;
r.popFront(); r.popFront();
source = JS_sprintf_append(source, "%s: %d%s", source = JS_sprintf_append(source, "%s: %d%s",
bytes.ptr(), shape.shortid, bytes.ptr(), shape.shortid,
!r.empty() ? ", " : ""); !r.empty() ? ", " : "");
if (!source)
return false;
} }
source = JS_sprintf_append(source, "}"); source = JS_sprintf_append(source, "}");
if (!source) if (!source)
return NULL; return false;
bytes->initBytes(source);
JSString *str = JS_NewString(cx, source, strlen(source)); return true;
if (!str)
return NULL;
return bytes->encode(cx, str);
} }
if (clasp == &js_FunctionClass) { if (clasp == &js_FunctionClass) {
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj); JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
JSString *str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT); JSString *str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT);
if (!str) if (!str)
return NULL; return false;
return bytes->encode(cx, str); return bytes->encode(cx, str);
} }
if (clasp == &js_RegExpClass) { if (clasp == &js_RegExpClass) {
AutoValueRooter tvr(cx); AutoValueRooter tvr(cx);
if (!js_regexp_toString(cx, obj, tvr.addr())) if (!js_regexp_toString(cx, obj, tvr.addr()))
return NULL; return false;
return bytes->encode(cx, JSVAL_TO_STRING(Jsvalify(tvr.value()))); return bytes->encode(cx, JSVAL_TO_STRING(Jsvalify(tvr.value())));
} }
} }

View File

@ -1014,11 +1014,10 @@ Options(JSContext *cx, uintN argc, jsval *vp)
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
return JS_FALSE; return JS_FALSE;
} }
str = JS_NewString(cx, names, strlen(names)); str = JS_NewStringCopyZ(cx, names);
if (!str) { free(names);
free(names); if (!str)
return JS_FALSE; return JS_FALSE;
}
*vp = STRING_TO_JSVAL(str); *vp = STRING_TO_JSVAL(str);
return JS_TRUE; return JS_TRUE;
} }
@ -1137,11 +1136,10 @@ ReadLine(JSContext *cx, uintN argc, jsval *vp)
* Turn buf into a JSString. Note that buflength includes the trailing null * Turn buf into a JSString. Note that buflength includes the trailing null
* character. * character.
*/ */
str = JS_NewString(cx, buf, sawNewline ? buflength - 1 : buflength); str = JS_NewStringCopyN(cx, buf, sawNewline ? buflength - 1 : buflength);
if (!str) { JS_free(cx, buf);
JS_free(cx, buf); if (!str)
return JS_FALSE; return JS_FALSE;
}
*vp = STRING_TO_JSVAL(str); *vp = STRING_TO_JSVAL(str);
return JS_TRUE; return JS_TRUE;
@ -4144,12 +4142,10 @@ Snarf(JSContext *cx, uintN argc, jsval *vp)
return ok; return ok;
} }
buf[len] = '\0'; str = JS_NewStringCopyN(cx, buf, len);
str = JS_NewString(cx, buf, len); JS_free(cx, buf);
if (!str) { if (!str)
JS_free(cx, buf);
return JS_FALSE; return JS_FALSE;
}
*vp = STRING_TO_JSVAL(str); *vp = STRING_TO_JSVAL(str);
return JS_TRUE; return JS_TRUE;
} }

View File

@ -824,11 +824,10 @@ Options(JSContext *cx, uintN argc, jsval *vp)
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
return JS_FALSE; return JS_FALSE;
} }
str = JS_NewString(cx, names, strlen(names)); str = JS_NewStringCopyZ(cx, names);
if (!str) { free(names);
free(names); if (!str)
return JS_FALSE; return JS_FALSE;
}
JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str)); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
} }

View File

@ -91,13 +91,10 @@ ToStringGuts(XPCCallContext& ccx)
return JS_FALSE; return JS_FALSE;
} }
JSString* str = JS_NewString(ccx, sz, strlen(sz)); JSString* str = JS_NewStringCopyZ(ccx, sz);
JS_smprintf_free(sz);
if(!str) if(!str)
{
JS_smprintf_free(sz);
// JS_ReportOutOfMemory already reported by failed JS_NewString
return JS_FALSE; return JS_FALSE;
}
ccx.SetRetVal(STRING_TO_JSVAL(str)); ccx.SetRetVal(STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
@ -129,13 +126,10 @@ XPC_WN_Shared_ToString(JSContext *cx, uintN argc, jsval *vp)
if(!sz) if(!sz)
return JS_FALSE; return JS_FALSE;
JSString* str = JS_NewString(cx, sz, strlen(sz)); JSString* str = JS_NewStringCopyZ(cx, sz);
JS_smprintf_free(sz);
if(!str) if(!str)
{
JS_smprintf_free(sz);
return JS_FALSE; return JS_FALSE;
}
*vp = STRING_TO_JSVAL(str); *vp = STRING_TO_JSVAL(str);