part of the fix for bug 67258 to avoid empry Components.results. r=dmose sr=brendan xpccomponents.cpp
git-svn-id: svn://10.0.0.236/trunk@86061 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -908,12 +908,30 @@ private:
|
||||
nsIXPConnectWrappedNative *wrapper,
|
||||
nsIXPCScriptable *arbitrary);
|
||||
|
||||
JSBool NeedToFillCache(JSObject* obj) const {return obj != mObj;}
|
||||
|
||||
private:
|
||||
JSBool mCacheFilled;
|
||||
//
|
||||
// This code used to just use a JSBool to track whether or not we had
|
||||
// already added the properties to the JSObject. The problem with that
|
||||
// scheme is that we are storing the flag here in this C++ object, but the
|
||||
// properties get added to the JSObject of the wrapper around this object.
|
||||
// Usually this worked fine. But in the cases where the wrapper was
|
||||
// garbage collected and a new wrapper created in its place our flag would
|
||||
// indicate that we'd added the properties, but those properties had been
|
||||
// added to the JSObject of the *old* wrapper but the new wrapper's JSObject
|
||||
// would not have the properties at all.
|
||||
//
|
||||
// So instead, we flag the addition of the properties by storing the
|
||||
// JSObject* on which we added the properties. If mObj equals the
|
||||
// current object then we know we've added the properties. Otherwise we
|
||||
// know we still need to add them.
|
||||
//
|
||||
JSObject* mObj;
|
||||
};
|
||||
|
||||
nsXPCComponents_Results::nsXPCComponents_Results()
|
||||
: mCacheFilled(JS_FALSE)
|
||||
: mObj(nsnull)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
@@ -950,7 +968,8 @@ nsXPCComponents_Results::FillCache(JSContext *cx, JSObject *obj,
|
||||
}
|
||||
}
|
||||
|
||||
mCacheFilled = JS_TRUE;
|
||||
// Indicate that we've added the properties to the current object.
|
||||
mObj = obj;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -992,7 +1011,7 @@ nsXPCComponents_Results::LookupProperty(JSContext *cx, JSObject *obj,
|
||||
nsIXPCScriptable* arbitrary,
|
||||
JSBool* retval)
|
||||
{
|
||||
if(!mCacheFilled)
|
||||
if(NeedToFillCache(obj))
|
||||
FillCache(cx, obj, wrapper, arbitrary);
|
||||
return arbitrary->LookupProperty(cx, obj, id, objp, propp, wrapper,
|
||||
nsnull, retval);
|
||||
@@ -1005,7 +1024,7 @@ nsXPCComponents_Results::GetProperty(JSContext *cx, JSObject *obj,
|
||||
nsIXPCScriptable* arbitrary,
|
||||
JSBool* retval)
|
||||
{
|
||||
if(!mCacheFilled)
|
||||
if(NeedToFillCache(obj))
|
||||
FillCache(cx, obj, wrapper, arbitrary);
|
||||
return arbitrary->GetProperty(cx, obj, id, vp, wrapper, nsnull, retval);
|
||||
}
|
||||
@@ -1019,7 +1038,7 @@ nsXPCComponents_Results::Enumerate(JSContext *cx, JSObject *obj,
|
||||
nsIXPCScriptable *arbitrary,
|
||||
JSBool *retval)
|
||||
{
|
||||
if(enum_op == JSENUMERATE_INIT && !mCacheFilled)
|
||||
if(enum_op == JSENUMERATE_INIT && NeedToFillCache(obj))
|
||||
FillCache(cx, obj, wrapper, arbitrary);
|
||||
|
||||
return arbitrary->Enumerate(cx, obj, enum_op, statep, idp, wrapper,
|
||||
|
||||
@@ -90,7 +90,7 @@ static uint8 xpc_reflectable_flags[XPC_FLAG_COUNT] = {
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_WCHAR */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* T_VOID */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_IID */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* T_DOMSTRING */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 0 ), /* T_DOMSTRING */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_CHAR_STR */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_WCHAR_STR */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_INTERFACE */
|
||||
@@ -347,9 +347,35 @@ XPCConvert::NativeData2JS(JSContext* cx, jsval* d, const void* s,
|
||||
}
|
||||
|
||||
case nsXPTType::T_DOMSTRING:
|
||||
// XXX implement DOMSTRING
|
||||
XPC_LOG_ERROR(("XPCConvert::NativeData2JS : DOMSTRING params not supported"));
|
||||
return JS_FALSE;
|
||||
{
|
||||
const nsAReadableString* p = *((const nsAReadableString**)s);
|
||||
if(!p)
|
||||
break;
|
||||
|
||||
PRUint32 length = p->Length();
|
||||
|
||||
jschar* chars = (jschar *)
|
||||
JS_malloc(cx, (length + 1) * sizeof(jschar));
|
||||
if(!chars)
|
||||
return JS_FALSE;
|
||||
|
||||
if(length && !CopyUnicodeTo(*p, 0, (PRUnichar*)chars, length))
|
||||
{
|
||||
JS_free(cx, chars);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
chars[length] = 0;
|
||||
|
||||
JSString* str;
|
||||
if(!(str = JS_NewUCString(cx, chars, length)))
|
||||
{
|
||||
JS_free(cx, chars);
|
||||
return JS_FALSE;
|
||||
}
|
||||
*d = STRING_TO_JSVAL(str);
|
||||
break;
|
||||
}
|
||||
|
||||
case nsXPTType::T_CHAR_STR:
|
||||
{
|
||||
@@ -586,6 +612,42 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
|
||||
}
|
||||
|
||||
case nsXPTType::T_DOMSTRING:
|
||||
{
|
||||
const PRUnichar* chars = nsnull;
|
||||
PRUint32 length;
|
||||
JSString* str;
|
||||
|
||||
if(!JSVAL_IS_VOID(s) && !JSVAL_IS_NULL(s) &&
|
||||
nsnull != (str = JS_ValueToString(cx, s)))
|
||||
{
|
||||
chars = (const PRUnichar*) JS_GetStringChars(str);
|
||||
length = (PRUint32) JS_GetStringLength(str);
|
||||
}
|
||||
|
||||
// XXX We don't yet have a way to represent a null nsAXXXString
|
||||
// (as opposed to one containing an empty string). This comes later.
|
||||
|
||||
const static PRUnichar* emptyString = NS_LITERAL_STRING("");
|
||||
if(!chars)
|
||||
{
|
||||
chars = emptyString;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if(useAllocator)
|
||||
{
|
||||
nsAReadableString* rs = new nsLiteralString(chars, length);
|
||||
if(!rs)
|
||||
return JS_FALSE;
|
||||
*((nsAReadableString**)d) = rs;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsAWritableString* ws = *((nsAWritableString**)d);
|
||||
ws->Assign(chars);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
// XXX implement DOMSTRING
|
||||
XPC_LOG_ERROR(("XPCConvert::JSData2Native : DOMSTRING params not supported"));
|
||||
return JS_FALSE;
|
||||
|
||||
@@ -274,7 +274,7 @@ XPC_IMPLEMENT_IGNORE_CONSTRUCT(nsJSIID)
|
||||
XPC_IMPLEMENT_FORWARD_FINALIZE(nsJSIID)
|
||||
|
||||
nsJSIID::nsJSIID()
|
||||
: mCacheFilled(JS_FALSE)
|
||||
: mObj(nsnull)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
@@ -479,7 +479,8 @@ nsJSIID::FillCache(JSContext *cx, JSObject *obj,
|
||||
}
|
||||
}
|
||||
|
||||
mCacheFilled = JS_TRUE;
|
||||
// Indicate that we've added the properties to the current object.
|
||||
mObj = obj;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -502,7 +503,7 @@ nsJSIID::LookupProperty(JSContext *cx, JSObject *obj,
|
||||
nsIXPCScriptable* arbitrary,
|
||||
JSBool* retval)
|
||||
{
|
||||
if(!mCacheFilled)
|
||||
if(NeedToFillCache(obj))
|
||||
FillCache(cx, obj, wrapper, arbitrary);
|
||||
return arbitrary->LookupProperty(cx, obj, id, objp, propp, wrapper,
|
||||
nsnull, retval);
|
||||
@@ -515,7 +516,7 @@ nsJSIID::GetProperty(JSContext *cx, JSObject *obj,
|
||||
nsIXPCScriptable* arbitrary,
|
||||
JSBool* retval)
|
||||
{
|
||||
if(!mCacheFilled)
|
||||
if(NeedToFillCache(obj))
|
||||
FillCache(cx, obj, wrapper, arbitrary);
|
||||
return arbitrary->GetProperty(cx, obj, id, vp, wrapper, nsnull, retval);
|
||||
}
|
||||
@@ -529,7 +530,7 @@ nsJSIID::Enumerate(JSContext *cx, JSObject *obj,
|
||||
nsIXPCScriptable *arbitrary,
|
||||
JSBool *retval)
|
||||
{
|
||||
if(enum_op == JSENUMERATE_INIT && !mCacheFilled)
|
||||
if(enum_op == JSENUMERATE_INIT && NeedToFillCache(obj))
|
||||
FillCache(cx, obj, wrapper, arbitrary);
|
||||
|
||||
return arbitrary->Enumerate(cx, obj, enum_op, statep, idp, wrapper,
|
||||
|
||||
Reference in New Issue
Block a user