Bug 577472 - Quickstub string handling shouldn't addref/release the string buffer, r=mrbkap

--HG--
extra : rebase_source : 5c343f210f3fb4a0aca5fc5f8b9b2d492248d3f3
This commit is contained in:
Olli Pettay 2010-07-19 13:34:23 +03:00
parent b956226bbf
commit 6f759b3d50
5 changed files with 48 additions and 7 deletions

View File

@ -3195,7 +3195,9 @@ class XPCStringConvert
{
public:
static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable);
static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
PRBool dontAddrefShared = PR_FALSE,
PRBool* sharedBuffer = nsnull);
static XPCReadableJSStringWrapper *JSStringToReadable(XPCCallContext& ccx,
JSString *str);

View File

@ -1058,7 +1058,7 @@ xpc_qsJsvalToWcharStr(JSContext *cx, jsval v, jsval *pval, PRUnichar **pstr)
}
JSBool
xpc_qsStringToJsval(JSContext *cx, const nsAString &str, jsval *rval)
xpc_qsStringToJsval(JSContext *cx, nsString &str, jsval *rval)
{
// From the T_DOMSTRING case in XPCConvert::NativeData2JS.
if(str.IsVoid())
@ -1067,10 +1067,18 @@ xpc_qsStringToJsval(JSContext *cx, const nsAString &str, jsval *rval)
return JS_TRUE;
}
jsval jsstr = XPCStringConvert::ReadableToJSVal(cx, str);
PRBool isShared = PR_FALSE;
jsval jsstr =
XPCStringConvert::ReadableToJSVal(cx, str, PR_TRUE, &isShared);
if(!jsstr)
return JS_FALSE;
*rval = jsstr;
if (isShared)
{
// The string was shared but ReadableToJSVal didn't addref it.
// Move the ownership from str to jsstr.
str.ForgetSharedBuffer();
}
return JS_TRUE;
}

View File

@ -347,9 +347,12 @@ JSBool
xpc_qsJsvalToWcharStr(JSContext *cx, jsval v, jsval *pval, PRUnichar **pstr);
/** Convert an nsAString to jsval, returning JS_TRUE on success. */
/** Convert an nsString to jsval, returning JS_TRUE on success.
* Note, the ownership of the string buffer may be moved from str to rval.
* If that happens, str will point to an empty string after this call.
*/
JSBool
xpc_qsStringToJsval(JSContext *cx, const nsAString &str, jsval *rval);
xpc_qsStringToJsval(JSContext *cx, nsString &str, jsval *rval);
nsresult
getWrapper(JSContext *cx,

View File

@ -77,9 +77,15 @@ XPCStringConvert::ShutdownDOMStringFinalizer()
// static
jsval
XPCStringConvert::ReadableToJSVal(JSContext *cx,
const nsAString &readable)
const nsAString &readable,
PRBool dontAddrefShared,
PRBool* sharedBuffer)
{
JSString *str;
if (sharedBuffer)
{
*sharedBuffer = PR_FALSE;
}
PRUint32 length = readable.Length();
@ -108,7 +114,16 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
length, sDOMStringFinalizerIndex);
if (str)
buf->AddRef();
{
if (sharedBuffer)
{
*sharedBuffer = PR_TRUE;
}
if (!dontAddrefShared)
{
buf->AddRef();
}
}
}
else
{

View File

@ -528,6 +528,19 @@ class nsTSubstring_CharT
NS_COM void StripChar( char_type aChar, PRInt32 aOffset=0 );
/**
* If the string uses a shared buffer, this method
* clears the pointer without releasing the buffer.
*/
void ForgetSharedBuffer()
{
if (mFlags & nsSubstring::F_SHARED)
{
mData = char_traits::sEmptyBuffer;
mLength = 0;
mFlags = F_TERMINATED;
}
}
public: