From 09217db7116fd8f61ba82cafe03b3e98b8bcc7c3 Mon Sep 17 00:00:00 2001 From: "dwitte@stanford.edu" Date: Thu, 10 Jan 2008 19:56:00 -0800 Subject: [PATCH] thoroughly whack mallocfest in nsID/nsJSID and friends. b=410250, r+sr=jst, a=blocking1.9+ --- caps/src/nsNullPrincipal.cpp | 9 +- caps/src/nsScriptSecurityManager.cpp | 8 +- content/xbl/src/nsXBLPrototypeBinding.cpp | 13 +- dom/src/base/nsDOMClassInfo.cpp | 30 ++- dom/src/base/nsScriptNameSpaceManager.cpp | 6 +- extensions/java/xpcom/src/nsJavaWrapper.cpp | 10 +- extensions/java/xpcom/src/nsJavaXPTCStub.cpp | 12 +- .../genifaces/GenerateJavaInterfaces.cpp | 13 +- .../python/xpcom/src/PyIInterfaceInfo.cpp | 3 +- js/src/xpconnect/idl/xpcjsid.idl | 15 +- js/src/xpconnect/src/xpccomponents.cpp | 7 +- js/src/xpconnect/src/xpcconvert.cpp | 3 +- js/src/xpconnect/src/xpcjsid.cpp | 194 ++++++++---------- js/src/xpconnect/src/xpcprivate.h | 6 +- js/src/xpconnect/src/xpcvariant.cpp | 9 +- js/src/xpconnect/src/xpcwrappednative.cpp | 4 +- .../components/places/src/nsNavBookmarks.cpp | 13 +- xpcom/glue/nsID.cpp | 13 +- xpcom/glue/nsID.h | 10 + xpcom/reflect/xptinfo/src/xptiManifest.cpp | 7 +- 20 files changed, 180 insertions(+), 205 deletions(-) diff --git a/caps/src/nsNullPrincipal.cpp b/caps/src/nsNullPrincipal.cpp index f66f7d510f99..51ec1b71ffaf 100644 --- a/caps/src/nsNullPrincipal.cpp +++ b/caps/src/nsNullPrincipal.cpp @@ -46,7 +46,6 @@ #include "nsMemory.h" #include "nsIUUIDGenerator.h" #include "nsID.h" -#include "prmem.h" // For PF_Free, 'cause nsID::ToString sucks like that #include "nsNetUtil.h" #include "nsIClassInfoImpl.h" #include "nsNetCID.h" @@ -105,10 +104,10 @@ nsNullPrincipal::Init() rv = uuidgen->GenerateUUIDInPlace(&id); NS_ENSURE_SUCCESS(rv, rv); - char* chars = id.ToString(); - NS_ENSURE_TRUE(chars, NS_ERROR_OUT_OF_MEMORY); + char chars[NSID_LENGTH]; + id.ToProvidedString(chars); - PRUint32 suffixLen = strlen(chars); + PRUint32 suffixLen = NSID_LENGTH - 1; PRUint32 prefixLen = NS_ARRAY_LENGTH(NS_NULLPRINCIPAL_PREFIX) - 1; // Use an nsCString so we only do the allocation once here and then share @@ -118,8 +117,6 @@ nsNullPrincipal::Init() str.Append(NS_NULLPRINCIPAL_PREFIX); str.Append(chars); - - PR_Free(chars); if (str.Length() != prefixLen + suffixLen) { NS_WARNING("Out of memory allocating null-principal URI"); diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index c066c142ff5b..0b02129b41f5 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -3072,8 +3072,8 @@ nsScriptSecurityManager::CanCreateInstance(JSContext *cx, { //-- Access denied, report an error nsCAutoString errorMsg("Permission denied to create instance of class. CID="); - nsXPIDLCString cidStr; - cidStr += aCID.ToString(); + char cidStr[NSID_LENGTH]; + aCID.ToProvidedString(cidStr); errorMsg.Append(cidStr); SetPendingException(cx, errorMsg.get()); @@ -3103,8 +3103,8 @@ nsScriptSecurityManager::CanGetService(JSContext *cx, { //-- Access denied, report an error nsCAutoString errorMsg("Permission denied to get service. CID="); - nsXPIDLCString cidStr; - cidStr += aCID.ToString(); + char cidStr[NSID_LENGTH]; + aCID.ToProvidedString(cidStr); errorMsg.Append(cidStr); SetPendingException(cx, errorMsg.get()); diff --git a/content/xbl/src/nsXBLPrototypeBinding.cpp b/content/xbl/src/nsXBLPrototypeBinding.cpp index 3f80837876e9..3ea85265a8c9 100644 --- a/content/xbl/src/nsXBLPrototypeBinding.cpp +++ b/content/xbl/src/nsXBLPrototypeBinding.cpp @@ -1349,8 +1349,8 @@ nsXBLPrototypeBinding::ConstructInterfaceTable(const nsAString& aImpls) if (iinfo) { // obtain an IID. - nsIID* iid = nsnull; - iinfo->GetInterfaceIID(&iid); + const nsIID* iid = nsnull; + iinfo->GetIIDShared(&iid); if (iid) { // We found a valid iid. Add it to our table. @@ -1362,11 +1362,8 @@ nsXBLPrototypeBinding::ConstructInterfaceTable(const nsAString& aImpls) nsCOMPtr parentInfo; // if it has a parent, add it to the table while (NS_SUCCEEDED(iinfo->GetParent(getter_AddRefs(parentInfo))) && parentInfo) { - // free the nsMemory::Clone()ed iid - nsMemory::Free(iid); - // get the iid - parentInfo->GetInterfaceIID(&iid); + parentInfo->GetIIDShared(&iid); // don't add nsISupports to the table if (!iid || iid->Equals(NS_GET_IID(nsISupports))) @@ -1380,10 +1377,6 @@ nsXBLPrototypeBinding::ConstructInterfaceTable(const nsAString& aImpls) iinfo = parentInfo; } } - - // free the nsMemory::Clone()ed iid - if (iid) - nsMemory::Free(iid); } token = nsCRT::strtok( newStr, ", ", &newStr ); diff --git a/dom/src/base/nsDOMClassInfo.cpp b/dom/src/base/nsDOMClassInfo.cpp index 40dd4b1947dc..9d3ca63df439 100644 --- a/dom/src/base/nsDOMClassInfo.cpp +++ b/dom/src/base/nsDOMClassInfo.cpp @@ -1706,24 +1706,20 @@ nsDOMClassInfo::RegisterClassProtos(PRInt32 aClassInfoID) iim->GetInfoForIID(primary_iid, getter_AddRefs(if_info)); while (if_info) { - nsIID *iid = nsnull; + const nsIID *iid = nsnull; - if_info->GetInterfaceIID(&iid); + if_info->GetIIDShared(&iid); NS_ENSURE_TRUE(iid, NS_ERROR_UNEXPECTED); if (iid->Equals(NS_GET_IID(nsISupports))) { - nsMemory::Free(iid); - break; } - nsXPIDLCString name; - if_info->GetName(getter_Copies(name)); + const char *name; + if_info->GetNameShared(&name); nameSpaceManager->RegisterClassProto(CutPrefix(name), iid, &found_old); - nsMemory::Free(iid); - if (first) { first = PR_FALSE; } else if (found_old) { @@ -5330,7 +5326,9 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, primary_iid = ci_data->mProtoChainInterface; } - nsXPIDLCString class_parent_name; + nsCOMPtr if_info; + nsCOMPtr parent; + const char *class_parent_name; if (!primary_iid->Equals(NS_GET_IID(nsISupports))) { rv = DefineInterfaceConstants(cx, class_obj, primary_iid); @@ -5356,20 +5354,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID)); NS_ENSURE_TRUE(iim, NS_ERROR_NOT_AVAILABLE); - nsCOMPtr if_info; iim->GetInfoForIID(primary_iid, getter_AddRefs(if_info)); NS_ENSURE_TRUE(if_info, NS_ERROR_UNEXPECTED); - nsCOMPtr parent; - nsIID *iid = nsnull; + const nsIID *iid = nsnull; if (ci_data && !ci_data->mHasClassInterface) { - if_info->GetInterfaceIID(&iid); + if_info->GetIIDShared(&iid); } else { if_info->GetParent(getter_AddRefs(parent)); NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED); - parent->GetInterfaceIID(&iid); + parent->GetIIDShared(&iid); } if (iid) { @@ -5379,7 +5375,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, // interface is the interface that should be // constructor.prototype.__proto__. - if_info->GetName(getter_Copies(class_parent_name)); + if_info->GetNameShared(&class_parent_name); } else { // If the class does have a class interface (or there's no // real class for this name) then the parent of the @@ -5388,11 +5384,9 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, NS_ASSERTION(parent, "Whoa, this is bad, null parent here!"); - parent->GetName(getter_Copies(class_parent_name)); + parent->GetNameShared(&class_parent_name); } } - - nsMemory::Free(iid); } } diff --git a/dom/src/base/nsScriptNameSpaceManager.cpp b/dom/src/base/nsScriptNameSpaceManager.cpp index 972d6a56d47e..069aba34846c 100644 --- a/dom/src/base/nsScriptNameSpaceManager.cpp +++ b/dom/src/base/nsScriptNameSpaceManager.cpp @@ -311,7 +311,7 @@ nsScriptNameSpaceManager::FillHashWithDOMInterfaces() PRBool found_old; nsCOMPtr if_info; - nsXPIDLCString if_name; + const char *if_name; const nsIID *iid; for ( ; domInterfaces->IsDone() == NS_ENUMERATOR_FALSE; domInterfaces->Next()) { @@ -319,9 +319,9 @@ nsScriptNameSpaceManager::FillHashWithDOMInterfaces() NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr if_info(do_QueryInterface(entry)); - if_info->GetName(getter_Copies(if_name)); + if_info->GetNameShared(&if_name); if_info->GetIIDShared(&iid); - rv = RegisterInterface(if_name.get() + sizeof(NS_DOM_INTERFACE_PREFIX) - 1, + rv = RegisterInterface(if_name + sizeof(NS_DOM_INTERFACE_PREFIX) - 1, iid, &found_old); #ifdef DEBUG diff --git a/extensions/java/xpcom/src/nsJavaWrapper.cpp b/extensions/java/xpcom/src/nsJavaWrapper.cpp index d38a092e5a9a..1868b4fb62e6 100644 --- a/extensions/java/xpcom/src/nsJavaWrapper.cpp +++ b/extensions/java/xpcom/src/nsJavaWrapper.cpp @@ -1137,15 +1137,13 @@ FinalizeParams(JNIEnv *env, const nsXPTParamInfo &aParamInfo, PRUint8 aType, // Create the string from nsID jstring str = nsnull; if (iid) { - char* iid_str = iid->ToString(); - if (iid_str) { - str = env->NewStringUTF(iid_str); - } - if (!iid_str || !str) { + char iid_str[NSID_LENGTH]; + iid->ToProvidedString(iid_str); + str = env->NewStringUTF(iid_str); + if (!str) { rv = NS_ERROR_OUT_OF_MEMORY; break; } - PR_Free(iid_str); } if (aParamInfo.IsRetval() && !aIsArrayElement) { diff --git a/extensions/java/xpcom/src/nsJavaXPTCStub.cpp b/extensions/java/xpcom/src/nsJavaXPTCStub.cpp index 229b0aeff443..0eb347516666 100644 --- a/extensions/java/xpcom/src/nsJavaXPTCStub.cpp +++ b/extensions/java/xpcom/src/nsJavaXPTCStub.cpp @@ -866,15 +866,13 @@ nsJavaXPTCStub::SetupJavaParams(const nsXPTParamInfo &aParamInfo, jobject str = nsnull; if (iid) { - char* iid_str = iid->ToString(); - if (iid_str) { - str = env->NewStringUTF(iid_str); - } - if (!iid_str || !str) { + char iid_str[NSID_LENGTH]; + iid->ToProvidedString(iid_str); + str = env->NewStringUTF(iid_str); + if (!str) { rv = NS_ERROR_OUT_OF_MEMORY; break; } - PR_Free(iid_str); } if (!aParamInfo.IsOut()) { // 'in' @@ -1710,4 +1708,4 @@ nsJavaXPTCStub::GetNewOrUsed(JNIEnv* env, jobject aJavaObject, *aResult = stub; return NS_OK; -} \ No newline at end of file +} diff --git a/extensions/java/xpcom/tools/genifaces/GenerateJavaInterfaces.cpp b/extensions/java/xpcom/tools/genifaces/GenerateJavaInterfaces.cpp index 35b1c7e371b3..6e92d56efca8 100644 --- a/extensions/java/xpcom/tools/genifaces/GenerateJavaInterfaces.cpp +++ b/extensions/java/xpcom/tools/genifaces/GenerateJavaInterfaces.cpp @@ -416,10 +416,8 @@ public: static const char kIIDDecl2[] = " =\n \""; static const char kIIDDecl3[] = "\";\n\n"; - nsIID* iid = nsnull; - aIInfo->GetInterfaceIID(&iid); - if (!iid) - return NS_ERROR_OUT_OF_MEMORY; + nsIID* iid; + aIInfo->GetIIDShared(&iid); // create iid field name nsCAutoString iid_name; @@ -435,9 +433,8 @@ public: ToUpperCase(iid_name); // get iid string - char* iid_str = iid->ToString(); - if (!iid_str) - return NS_ERROR_OUT_OF_MEMORY; + char iid_str[NSID_LENGTH]; + iid->ToProvidedString(iid_str); PRUint32 count; nsresult rv = out->Write(kIIDDecl1, sizeof(kIIDDecl1) - 1, &count); @@ -452,8 +449,6 @@ public: NS_ENSURE_SUCCESS(rv, rv); // cleanup - PR_Free(iid_str); - nsMemory::Free(iid); return NS_OK; } diff --git a/extensions/python/xpcom/src/PyIInterfaceInfo.cpp b/extensions/python/xpcom/src/PyIInterfaceInfo.cpp index 0c8b9723c4f8..5f13e51a9644 100644 --- a/extensions/python/xpcom/src/PyIInterfaceInfo.cpp +++ b/extensions/python/xpcom/src/PyIInterfaceInfo.cpp @@ -91,12 +91,11 @@ static PyObject *PyGetIID(PyObject *self, PyObject *args) nsIID *iid_ret; nsresult r; Py_BEGIN_ALLOW_THREADS; - r = pI->GetInterfaceIID(&iid_ret); + r = pI->GetIIDShared(&iid_ret); Py_END_ALLOW_THREADS; if ( NS_FAILED(r) ) return PyXPCOM_BuildPyException(r); PyObject *ret = Py_nsIID::PyObjectFromIID(*iid_ret); - nsMemory::Free(iid_ret); return ret; } diff --git a/js/src/xpconnect/idl/xpcjsid.idl b/js/src/xpconnect/idl/xpcjsid.idl index 654715cae07e..02c7b94ba716 100644 --- a/js/src/xpconnect/idl/xpcjsid.idl +++ b/js/src/xpconnect/idl/xpcjsid.idl @@ -40,19 +40,24 @@ #include "nsISupports.idl" -[scriptable, uuid(C86AE131-D101-11d2-9841-006008962422)] +[ptr] native const_nsID_ptr(const nsID); + +[scriptable, uuid(baedc96a-9cee-4b6b-9160-90d257b3c8ef)] interface nsIJSID : nsISupports { - readonly attribute string name; - readonly attribute string number; - [noscript] readonly attribute nsIDPtr id; - readonly attribute boolean valid; + readonly attribute string name; + readonly attribute string number; + readonly attribute boolean valid; boolean equals(in nsIJSID other); void initialize(in string idString); string toString(); + + // returns a pointer to the internal nsID. this pointer is only valid + // while the nsIJSID object remains alive! + [notxpcom] const_nsID_ptr getID(); }; [scriptable, uuid(e08dcda0-d651-11d2-9843-006008962422)] diff --git a/js/src/xpconnect/src/xpccomponents.cpp b/js/src/xpconnect/src/xpccomponents.cpp index 1dfcd4b83fe1..f83bdba1b4b6 100644 --- a/js/src/xpconnect/src/xpccomponents.cpp +++ b/js/src/xpconnect/src/xpccomponents.cpp @@ -622,7 +622,7 @@ nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper, if(iface) { nsIID const *iid; - char* idstr; + char idstr[NSID_LENGTH]; JSString* jsstr; PRBool scriptable; @@ -632,11 +632,10 @@ nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper, continue; } - if(NS_SUCCEEDED(iface->GetIIDShared(&iid)) && - nsnull != (idstr = iid->ToString())) + if(NS_SUCCEEDED(iface->GetIIDShared(&iid))) { + iid->ToProvidedString(idstr); jsstr = JS_NewStringCopyZ(cx, idstr); - nsMemory::Free(idstr); if (jsstr && JS_ValueToId(cx, STRING_TO_JSVAL(jsstr), idp)) { diff --git a/js/src/xpconnect/src/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp index 5d6f8cbb3caa..e03fac2ede0b 100644 --- a/js/src/xpconnect/src/xpcconvert.cpp +++ b/js/src/xpconnect/src/xpcconvert.cpp @@ -669,7 +669,8 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s, if(!JSVAL_IS_OBJECT(s) || (!(obj = JSVAL_TO_OBJECT(s))) || - (!(pid = xpc_JSObjectToID(cx, obj)))) + (!(pid = xpc_JSObjectToID(cx, obj))) || + (!(pid = (const nsID*) nsMemory::Clone(pid, sizeof(nsID))))) { return JS_FALSE; } diff --git a/js/src/xpconnect/src/xpcjsid.cpp b/js/src/xpconnect/src/xpcjsid.cpp index ee0d80b3b42c..1fa1186cdfd2 100644 --- a/js/src/xpconnect/src/xpcjsid.cpp +++ b/js/src/xpconnect/src/xpcjsid.cpp @@ -117,14 +117,10 @@ nsJSID::GetNumber(char * *aNumber) return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } -NS_IMETHODIMP -nsJSID::GetId(nsID* *aId) +NS_IMETHODIMP_(const nsID*) +nsJSID::GetID() { - if(!aId) - return NS_ERROR_NULL_POINTER; - - *aId = (nsID*) nsMemory::Clone(&mID, sizeof(nsID)); - return *aId ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + return &mID; } NS_IMETHODIMP @@ -143,17 +139,13 @@ nsJSID::Equals(nsIJSID *other, PRBool *_retval) if(!_retval) return NS_ERROR_NULL_POINTER; - *_retval = PR_FALSE; - if(!other || mID.Equals(GetInvalidIID())) - return NS_OK; - - nsID* otherID; - if(NS_SUCCEEDED(other->GetId(&otherID))) { - *_retval = mID.Equals(*otherID); - nsMemory::Free(otherID); + *_retval = PR_FALSE; + return NS_OK; } + + *_retval = other->GetID()->Equals(mID); return NS_OK; } @@ -163,23 +155,22 @@ nsJSID::Initialize(const char *idString) if(!idString) return NS_ERROR_NULL_POINTER; - PRBool success = PR_FALSE; - if(strlen(idString) && mID.Equals(GetInvalidIID())) { Reset(); if(idString[0] == '{') { - nsID id; - if(id.Parse((char*)idString)) + if(mID.Parse(idString)) { - mID = id; - success = PR_TRUE; + return NS_OK; } + + // error - reset to invalid state + mID = GetInvalidIID(); } } - return success ? NS_OK : NS_ERROR_FAILURE; + return NS_ERROR_FAILURE; } PRBool @@ -241,6 +232,20 @@ nsJSID::NewID(const char* str) return idObj; } +//static +nsJSID* +nsJSID::NewID(const nsID& id) +{ + nsJSID* idObj = new nsJSID(); + if(idObj) + { + NS_ADDREF(idObj); + idObj->mID = id; + } + return idObj; +} + + /***************************************************************************/ // Class object support so that we can share prototypes of wrapper @@ -412,19 +417,19 @@ NS_IMETHODIMP nsJSIID::GetName(char * *aName) NS_IMETHODIMP nsJSIID::GetNumber(char * *aNumber) { + char str[NSID_LENGTH]; const nsIID* id; mInfo->GetIIDShared(&id); - char* str = id->ToString(); - if(!str) - return NS_ERROR_OUT_OF_MEMORY; - *aNumber = (char*) nsMemory::Clone(str, strlen(str)+1); - PR_Free(str); + id->ToProvidedString(str); + *aNumber = (char*) nsMemory::Clone(str, NSID_LENGTH); return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } -NS_IMETHODIMP nsJSIID::GetId(nsID* *aId) +NS_IMETHODIMP_(const nsID*) nsJSIID::GetID() { - return mInfo->GetInterfaceIID((nsIID**)aId); + const nsIID* id; + mInfo->GetIIDShared(&id); + return id; } NS_IMETHODIMP nsJSIID::GetValid(PRBool *aValid) @@ -438,17 +443,13 @@ NS_IMETHODIMP nsJSIID::Equals(nsIJSID *other, PRBool *_retval) if(!_retval) return NS_ERROR_NULL_POINTER; - *_retval = PR_FALSE; - if(!other) - return NS_OK; - - nsID* otherID; - if(NS_SUCCEEDED(other->GetId(&otherID))) { - mInfo->IsIID((nsIID*)otherID, _retval); - nsMemory::Free(otherID); + *_retval = PR_FALSE; + return NS_OK; } + + mInfo->IsIID(other->GetID(), _retval); return NS_OK; } @@ -673,8 +674,8 @@ NS_IMETHODIMP nsJSCID::GetName(char * *aName) NS_IMETHODIMP nsJSCID::GetNumber(char * *aNumber) {return mDetails.GetNumber(aNumber);} -NS_IMETHODIMP nsJSCID::GetId(nsID* *aId) - {return mDetails.GetId(aId);} +NS_IMETHODIMP_(const nsID*) nsJSCID::GetID() + {return &mDetails.ID();} NS_IMETHODIMP nsJSCID::GetValid(PRBool *aValid) {return mDetails.GetValid(aValid);} @@ -736,6 +737,28 @@ nsJSCID::NewID(const char* str) return idObj; } +static const nsID* +GetIIDArg(PRUint32 argc, jsval* argv, JSContext* cx) +{ + const nsID* iid; + + // If an IID was passed in then use it + if(argc) + { + JSObject* iidobj; + jsval val = *argv; + if(JSVAL_IS_PRIMITIVE(val) || + !(iidobj = JSVAL_TO_OBJECT(val)) || + !(iid = xpc_JSObjectToID(cx, iidobj))) + { + return nsnull; + } + } + else + iid = &NS_GET_IID(nsISupports); + + return iid; +} /* nsISupports createInstance (); */ NS_IMETHODIMP @@ -775,32 +798,17 @@ nsJSCID::CreateInstance(nsISupports **_retval) nsIXPCSecurityManager* sm; sm = xpcc->GetAppropriateSecurityManager( nsIXPCSecurityManager::HOOK_CREATE_INSTANCE); - if(sm && NS_FAILED(sm->CanCreateInstance(cx, *mDetails.GetID()))) + if(sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) { // the security manager vetoed. It should have set an exception. ccxp->SetExceptionWasThrown(JS_TRUE); return NS_OK; } - nsID iid; - // If an IID was passed in then use it - if(argc) - { - JSObject* iidobj; - jsval val = *argv; - nsID* piid = nsnull; - if(JSVAL_IS_PRIMITIVE(val) || - !(iidobj = JSVAL_TO_OBJECT(val)) || - !(piid = xpc_JSObjectToID(cx, iidobj))) - { - return NS_ERROR_XPC_BAD_IID; - } - iid = *piid; - nsMemory::Free(piid); - } - else - iid = NS_GET_IID(nsISupports); + const nsID* iid = GetIIDArg(argc, argv, cx); + if (!iid) + return NS_ERROR_XPC_BAD_IID; nsCOMPtr compMgr; nsresult rv = NS_GetComponentManager(getter_AddRefs(compMgr)); @@ -808,7 +816,7 @@ nsJSCID::CreateInstance(nsISupports **_retval) return NS_ERROR_UNEXPECTED; nsCOMPtr inst; - rv = compMgr->CreateInstance(*mDetails.GetID(), nsnull, iid, getter_AddRefs(inst)); + rv = compMgr->CreateInstance(mDetails.ID(), nsnull, *iid, getter_AddRefs(inst)); NS_ASSERTION(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!"); if(NS_FAILED(rv) || !inst) @@ -816,7 +824,7 @@ nsJSCID::CreateInstance(nsISupports **_retval) JSObject* instJSObj; nsCOMPtr holder; - rv = xpc->WrapNative(cx, obj, inst, iid, getter_AddRefs(holder)); + rv = xpc->WrapNative(cx, obj, inst, *iid, getter_AddRefs(holder)); if(NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(&instJSObj))) return NS_ERROR_XPC_CANT_CREATE_WN; @@ -863,32 +871,17 @@ nsJSCID::GetService(nsISupports **_retval) nsIXPCSecurityManager* sm; sm = xpcc->GetAppropriateSecurityManager( nsIXPCSecurityManager::HOOK_GET_SERVICE); - if(sm && NS_FAILED(sm->CanCreateInstance(cx, *mDetails.GetID()))) + if(sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) { // the security manager vetoed. It should have set an exception. ccxp->SetExceptionWasThrown(JS_TRUE); return NS_OK; } - nsID iid; - // If an IID was passed in then use it - if(argc) - { - JSObject* iidobj; - jsval val = *argv; - nsID* piid = nsnull; - if(JSVAL_IS_PRIMITIVE(val) || - !(iidobj = JSVAL_TO_OBJECT(val)) || - !(piid = xpc_JSObjectToID(cx, iidobj))) - { - return NS_ERROR_XPC_BAD_IID; - } - iid = *piid; - nsMemory::Free(piid); - } - else - iid = NS_GET_IID(nsISupports); + const nsID* iid = GetIIDArg(argc, argv, cx); + if (!iid) + return NS_ERROR_XPC_BAD_IID; nsCOMPtr svcMgr; nsresult rv = NS_GetServiceManager(getter_AddRefs(svcMgr)); @@ -896,14 +889,14 @@ nsJSCID::GetService(nsISupports **_retval) return rv; nsCOMPtr srvc; - rv = svcMgr->GetService(*mDetails.GetID(), iid, getter_AddRefs(srvc)); + rv = svcMgr->GetService(mDetails.ID(), *iid, getter_AddRefs(srvc)); NS_ASSERTION(NS_FAILED(rv) || srvc, "service manager returned success, but service is null!"); if(NS_FAILED(rv) || !srvc) return NS_ERROR_XPC_GS_RETURNED_FAILURE; JSObject* instJSObj; nsCOMPtr holder; - rv = xpc->WrapNative(cx, obj, srvc, iid, getter_AddRefs(holder)); + rv = xpc->WrapNative(cx, obj, srvc, *iid, getter_AddRefs(holder)); if(NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(&instJSObj))) return NS_ERROR_XPC_CANT_CREATE_WN; @@ -962,7 +955,7 @@ nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper, { nsID cid; if(NS_SUCCEEDED(ci->GetClassIDNoAlloc(&cid))) - *bp = cid.Equals(*mDetails.GetID()); + *bp = cid.Equals(mDetails.ID()); } } return rv; @@ -976,36 +969,31 @@ xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID) { JSObject *obj = nsnull; - char* idString = aID.ToString(); - if(idString) + nsCOMPtr iid = + dont_AddRef(static_cast(nsJSID::NewID(aID))); + if(iid) { - nsCOMPtr iid = - dont_AddRef(static_cast(nsJSID::NewID(idString))); - PR_Free(idString); - if(iid) + nsXPConnect* xpc = nsXPConnect::GetXPConnect(); + if(xpc) { - nsXPConnect* xpc = nsXPConnect::GetXPConnect(); - if(xpc) + nsCOMPtr holder; + nsresult rv = xpc->WrapNative(cx, jsobj, + static_cast(iid), + NS_GET_IID(nsIJSID), + getter_AddRefs(holder)); + if(NS_SUCCEEDED(rv) && holder) { - nsCOMPtr holder; - nsresult rv = xpc->WrapNative(cx, jsobj, - static_cast(iid), - NS_GET_IID(nsIJSID), - getter_AddRefs(holder)); - if(NS_SUCCEEDED(rv) && holder) - { - holder->GetJSObject(&obj); - } + holder->GetJSObject(&obj); } } } return obj; } -nsID* +// note: returned pointer is only valid while |obj| remains alive! +const nsID* xpc_JSObjectToID(JSContext *cx, JSObject* obj) { - nsID* id = nsnull; if(!cx || !obj) return nsnull; @@ -1017,9 +1005,9 @@ xpc_JSObjectToID(JSContext *cx, JSObject* obj) wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID)))) { - ((nsIJSID*)wrapper->GetIdentityObject())->GetId(&id); + return ((nsIJSID*)wrapper->GetIdentityObject())->GetID(); } - return id; + return nsnull; } JSBool diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index 87ca5e24fc63..b89523fe8a09 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -2852,11 +2852,11 @@ public: void SetNameToNoString() {NS_ASSERTION(!mName, "name already set"); mName = gNoString;} PRBool NameIsSet() const {return nsnull != mName;} - const nsID* GetID() const {return &mID;} - + const nsID& ID() const {return mID;} PRBool IsValid() const {return !mID.Equals(GetInvalidIID());} static nsJSID* NewID(const char* str); + static nsJSID* NewID(const nsID& id); nsJSID(); virtual ~nsJSID(); @@ -3316,7 +3316,7 @@ private: extern JSObject* xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID); -extern nsID* +extern const nsID* xpc_JSObjectToID(JSContext *cx, JSObject* obj); extern JSBool diff --git a/js/src/xpconnect/src/xpcvariant.cpp b/js/src/xpconnect/src/xpcvariant.cpp index 1369219b4f15..bd82608b98f0 100644 --- a/js/src/xpconnect/src/xpcvariant.cpp +++ b/js/src/xpconnect/src/xpcvariant.cpp @@ -320,14 +320,9 @@ JSBool XPCVariant::InitializeData(XPCCallContext& ccx) // Let's see if it is a xpcJSID. - // XXX It might be nice to have a non-allocing version of xpc_JSObjectToID. - nsID* id = xpc_JSObjectToID(ccx, jsobj); + const nsID* id = xpc_JSObjectToID(ccx, jsobj); if(id) - { - JSBool success = NS_SUCCEEDED(nsVariant::SetFromID(&mData, *id)); - nsMemory::Free((char*)id); - return success; - } + return NS_SUCCEEDED(nsVariant::SetFromID(&mData, *id)); // Let's see if it is a js array object. diff --git a/js/src/xpconnect/src/xpcwrappednative.cpp b/js/src/xpconnect/src/xpcwrappednative.cpp index 9254c916f767..6cd71b87e037 100644 --- a/js/src/xpconnect/src/xpcwrappednative.cpp +++ b/js/src/xpconnect/src/xpcwrappednative.cpp @@ -1950,7 +1950,7 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx, Throw(NS_ERROR_XPC_NOT_ENOUGH_ARGS, ccx); return JS_FALSE; } - nsID* iid; + const nsID* iid; JSObject* obj; if(!JSVAL_IS_OBJECT(argv[0]) || (!(obj = JSVAL_TO_OBJECT(argv[0]))) || @@ -1971,7 +1971,6 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx, if(NS_FAILED(invokeResult)) { ThrowBadResult(invokeResult, ccx); - PR_Free(iid); return JS_FALSE; } @@ -1979,7 +1978,6 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx, retval = XPCConvert::NativeData2JS(ccx, &v, &qiresult, nsXPTType::T_INTERFACE_IS | XPT_TDP_POINTER, iid, ccx.GetCurrentJSObject(), &err); - PR_Free(iid); NS_IF_RELEASE(qiresult); if(!retval) diff --git a/toolkit/components/places/src/nsNavBookmarks.cpp b/toolkit/components/places/src/nsNavBookmarks.cpp index f6f3014391ce..0fc6612cbfbe 100644 --- a/toolkit/components/places/src/nsNavBookmarks.cpp +++ b/toolkit/components/places/src/nsNavBookmarks.cpp @@ -49,7 +49,6 @@ #include "nsPrintfCString.h" #include "nsAutoLock.h" #include "nsIUUIDGenerator.h" -#include "prmem.h" #include "prprf.h" const PRInt32 nsNavBookmarks::kFindBookmarksIndex_ID = 0; @@ -279,10 +278,9 @@ nsNavBookmarks::Init() nsID GUID; rv = uuidgen->GenerateUUIDInPlace(&GUID); NS_ENSURE_SUCCESS(rv, rv); - char* GUIDChars = GUID.ToString(); - NS_ENSURE_TRUE(GUIDChars, NS_ERROR_OUT_OF_MEMORY); - mGUIDBase.Assign(NS_ConvertASCIItoUTF16(GUIDChars)); - PR_Free(GUIDChars); + char GUIDChars[NSID_LENGTH]; + GUID.ToProvidedString(GUIDChars); + CopyASCIItoUTF16(GUIDChars, mGUIDBase); rv = InitRoots(); NS_ENSURE_SUCCESS(rv, rv); @@ -1739,9 +1737,10 @@ nsNavBookmarks::GetItemGUID(PRInt64 aItemId, nsAString &aGUID) return rv; nsAutoString tmp; - tmp.Assign(mGUIDBase); tmp.AppendInt(mItemCount++); - aGUID.Assign(tmp); + aGUID.SetCapacity(NSID_LENGTH - 1 + tmp.Length()); + aGUID.Assign(mGUIDBase); + aGUID.Append(tmp); return SetItemGUID(aItemId, aGUID); } diff --git a/xpcom/glue/nsID.cpp b/xpcom/glue/nsID.cpp index a0f55bf8c799..50f76a3af8fd 100644 --- a/xpcom/glue/nsID.cpp +++ b/xpcom/glue/nsID.cpp @@ -126,10 +126,10 @@ PRBool nsID::Parse(const char *aIDStr) char *nsID::ToString() const { - char *res = (char*)PR_Malloc(39); // use PR_Malloc if this is to be freed with nsCRT::free + char *res = (char*)PR_Malloc(NSID_LENGTH); // use PR_Malloc if this is to be freed with nsCRT::free if (res != NULL) { - PR_snprintf(res, 39, gIDFormat, + PR_snprintf(res, NSID_LENGTH, gIDFormat, m0, (PRUint32) m1, (PRUint32) m2, (PRUint32) m3[0], (PRUint32) m3[1], (PRUint32) m3[2], (PRUint32) m3[3], (PRUint32) m3[4], (PRUint32) m3[5], @@ -138,3 +138,12 @@ char *nsID::ToString() const return res; } +void nsID::ToProvidedString(char (&dest)[NSID_LENGTH]) const +{ + PR_snprintf(dest, NSID_LENGTH, gIDFormat, + m0, (PRUint32) m1, (PRUint32) m2, + (PRUint32) m3[0], (PRUint32) m3[1], (PRUint32) m3[2], + (PRUint32) m3[3], (PRUint32) m3[4], (PRUint32) m3[5], + (PRUint32) m3[6], (PRUint32) m3[7]); +} + diff --git a/xpcom/glue/nsID.h b/xpcom/glue/nsID.h index 5744244dee8d..070d81860cd7 100644 --- a/xpcom/glue/nsID.h +++ b/xpcom/glue/nsID.h @@ -44,6 +44,8 @@ #include "nscore.h" #endif +#define NSID_LENGTH 39 + /** * A "unique identifier". This is modeled after OSF DCE UUIDs. * @status FROZEN @@ -95,8 +97,16 @@ struct nsID { /** * nsID string encoder. Returns an allocated string in * {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Caller should free string. + * YOU SHOULD ONLY USE THIS IF YOU CANNOT USE ToProvidedString() BELOW. */ NS_COM_GLUE char* ToString() const; + + /** + * nsID string encoder. Builds a string in + * {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format, into a char[NSID_LENGTH] + * buffer provided by the caller (for instance, on the stack). + */ + NS_COM_GLUE void ToProvidedString(char (&dest)[NSID_LENGTH]) const; //@} }; diff --git a/xpcom/reflect/xptinfo/src/xptiManifest.cpp b/xpcom/reflect/xptinfo/src/xptiManifest.cpp index 4ac47a4a263f..94dd1414a4e2 100644 --- a/xpcom/reflect/xptinfo/src/xptiManifest.cpp +++ b/xpcom/reflect/xptinfo/src/xptiManifest.cpp @@ -96,9 +96,8 @@ xpti_InterfaceWriter(PLDHashTable *table, PLDHashEntryHdr *hdr, xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value; PRFileDesc* fd = (PRFileDesc*) arg; - char* iidStr = entry->GetTheIID()->ToString(); - if(!iidStr) - return PL_DHASH_STOP; + char iidStr[NSID_LENGTH]; + entry->GetTheIID()->ToProvidedString(iidStr); const xptiTypelib& typelib = entry->GetTypelibRecord(); @@ -111,8 +110,6 @@ xpti_InterfaceWriter(PLDHashTable *table, PLDHashEntryHdr *hdr, typelib.GetZipItemIndex() : -1), (int) entry->GetScriptableFlag()); - nsCRT::free(iidStr); - return success ? PL_DHASH_NEXT : PL_DHASH_STOP; }