diff --git a/js/src/xpconnect/idl/xpcjsid.idl b/js/src/xpconnect/idl/xpcjsid.idl index 02c7b94ba71..654715cae07 100644 --- a/js/src/xpconnect/idl/xpcjsid.idl +++ b/js/src/xpconnect/idl/xpcjsid.idl @@ -40,24 +40,19 @@ #include "nsISupports.idl" -[ptr] native const_nsID_ptr(const nsID); - -[scriptable, uuid(baedc96a-9cee-4b6b-9160-90d257b3c8ef)] +[scriptable, uuid(C86AE131-D101-11d2-9841-006008962422)] interface nsIJSID : nsISupports { - readonly attribute string name; - readonly attribute string number; - readonly attribute boolean valid; + readonly attribute string name; + readonly attribute string number; + [noscript] readonly attribute nsIDPtr id; + 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/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp index e03fac2ede0..5d6f8cbb3ca 100644 --- a/js/src/xpconnect/src/xpcconvert.cpp +++ b/js/src/xpconnect/src/xpcconvert.cpp @@ -669,8 +669,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s, if(!JSVAL_IS_OBJECT(s) || (!(obj = JSVAL_TO_OBJECT(s))) || - (!(pid = xpc_JSObjectToID(cx, obj))) || - (!(pid = (const nsID*) nsMemory::Clone(pid, sizeof(nsID))))) + (!(pid = xpc_JSObjectToID(cx, obj)))) { return JS_FALSE; } diff --git a/js/src/xpconnect/src/xpcjsid.cpp b/js/src/xpconnect/src/xpcjsid.cpp index c4be2e6a388..ee0d80b3b42 100644 --- a/js/src/xpconnect/src/xpcjsid.cpp +++ b/js/src/xpconnect/src/xpcjsid.cpp @@ -117,10 +117,14 @@ nsJSID::GetNumber(char * *aNumber) return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } -NS_IMETHODIMP_(const nsID*) -nsJSID::GetID() +NS_IMETHODIMP +nsJSID::GetId(nsID* *aId) { - return &mID; + if(!aId) + return NS_ERROR_NULL_POINTER; + + *aId = (nsID*) nsMemory::Clone(&mID, sizeof(nsID)); + return *aId ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } NS_IMETHODIMP @@ -139,13 +143,17 @@ nsJSID::Equals(nsIJSID *other, PRBool *_retval) if(!_retval) return NS_ERROR_NULL_POINTER; - if(!other || mID.Equals(GetInvalidIID())) - { - *_retval = PR_FALSE; - return NS_OK; - } + *_retval = PR_FALSE; - *_retval = other->GetID()->Equals(mID); + if(!other || mID.Equals(GetInvalidIID())) + return NS_OK; + + nsID* otherID; + if(NS_SUCCEEDED(other->GetId(&otherID))) + { + *_retval = mID.Equals(*otherID); + nsMemory::Free(otherID); + } return NS_OK; } @@ -155,22 +163,23 @@ 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] == '{') { - if(mID.Parse(idString)) + nsID id; + if(id.Parse((char*)idString)) { - return NS_OK; + mID = id; + success = PR_TRUE; } - - // error - reset to invalid state - mID = GetInvalidIID(); } } - return NS_ERROR_FAILURE; + return success ? NS_OK : NS_ERROR_FAILURE; } PRBool @@ -232,20 +241,6 @@ 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 @@ -417,19 +412,19 @@ NS_IMETHODIMP nsJSIID::GetName(char * *aName) NS_IMETHODIMP nsJSIID::GetNumber(char * *aNumber) { - char str[NSID_LENGTH]; const nsIID* id; mInfo->GetIIDShared(&id); - id->ToProvidedString(str); - *aNumber = (char*) nsMemory::Clone(str, NSID_LENGTH); + char* str = id->ToString(); + if(!str) + return NS_ERROR_OUT_OF_MEMORY; + *aNumber = (char*) nsMemory::Clone(str, strlen(str)+1); + PR_Free(str); return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } -NS_IMETHODIMP_(const nsID*) nsJSIID::GetID() +NS_IMETHODIMP nsJSIID::GetId(nsID* *aId) { - const nsIID* id; - mInfo->GetIIDShared(&id); - return id; + return mInfo->GetInterfaceIID((nsIID**)aId); } NS_IMETHODIMP nsJSIID::GetValid(PRBool *aValid) @@ -443,13 +438,17 @@ NS_IMETHODIMP nsJSIID::Equals(nsIJSID *other, PRBool *_retval) if(!_retval) return NS_ERROR_NULL_POINTER; - if(!other) - { - *_retval = PR_FALSE; - return NS_OK; - } + *_retval = PR_FALSE; - mInfo->IsIID(other->GetID(), _retval); + if(!other) + return NS_OK; + + nsID* otherID; + if(NS_SUCCEEDED(other->GetId(&otherID))) + { + mInfo->IsIID((nsIID*)otherID, _retval); + nsMemory::Free(otherID); + } return NS_OK; } @@ -674,8 +673,8 @@ NS_IMETHODIMP nsJSCID::GetName(char * *aName) NS_IMETHODIMP nsJSCID::GetNumber(char * *aNumber) {return mDetails.GetNumber(aNumber);} -NS_IMETHODIMP_(const nsID*) nsJSCID::GetID() - {return &mDetails.ID();} +NS_IMETHODIMP nsJSCID::GetId(nsID* *aId) + {return mDetails.GetId(aId);} NS_IMETHODIMP nsJSCID::GetValid(PRBool *aValid) {return mDetails.GetValid(aValid);} @@ -737,29 +736,7 @@ 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 nsJSCID::CreateInstance(nsISupports **_retval) @@ -798,17 +775,32 @@ nsJSCID::CreateInstance(nsISupports **_retval) nsIXPCSecurityManager* sm; sm = xpcc->GetAppropriateSecurityManager( nsIXPCSecurityManager::HOOK_CREATE_INSTANCE); - if(sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) + if(sm && NS_FAILED(sm->CanCreateInstance(cx, *mDetails.GetID()))) { // 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 - const nsID* iid = GetIIDArg(argc, argv, cx); - if (!iid) - return NS_ERROR_XPC_BAD_IID; + 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); nsCOMPtr compMgr; nsresult rv = NS_GetComponentManager(getter_AddRefs(compMgr)); @@ -816,7 +808,7 @@ nsJSCID::CreateInstance(nsISupports **_retval) return NS_ERROR_UNEXPECTED; nsCOMPtr inst; - rv = compMgr->CreateInstance(mDetails.ID(), nsnull, *iid, getter_AddRefs(inst)); + rv = compMgr->CreateInstance(*mDetails.GetID(), nsnull, iid, getter_AddRefs(inst)); NS_ASSERTION(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!"); if(NS_FAILED(rv) || !inst) @@ -824,7 +816,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; @@ -871,17 +863,32 @@ nsJSCID::GetService(nsISupports **_retval) nsIXPCSecurityManager* sm; sm = xpcc->GetAppropriateSecurityManager( nsIXPCSecurityManager::HOOK_GET_SERVICE); - if(sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) + if(sm && NS_FAILED(sm->CanCreateInstance(cx, *mDetails.GetID()))) { // 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 - const nsID* iid = GetIIDArg(argc, argv, cx); - if (!iid) - return NS_ERROR_XPC_BAD_IID; + 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); nsCOMPtr svcMgr; nsresult rv = NS_GetServiceManager(getter_AddRefs(svcMgr)); @@ -889,14 +896,14 @@ nsJSCID::GetService(nsISupports **_retval) return rv; nsCOMPtr srvc; - rv = svcMgr->GetService(mDetails.ID(), *iid, getter_AddRefs(srvc)); + rv = svcMgr->GetService(*mDetails.GetID(), 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; @@ -955,7 +962,7 @@ nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper, { nsID cid; if(NS_SUCCEEDED(ci->GetClassIDNoAlloc(&cid))) - *bp = cid.Equals(mDetails.ID()); + *bp = cid.Equals(*mDetails.GetID()); } } return rv; @@ -969,31 +976,36 @@ xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID) { JSObject *obj = nsnull; - nsCOMPtr iid = - dont_AddRef(static_cast(nsJSID::NewID(aID))); - if(iid) + char* idString = aID.ToString(); + if(idString) { - nsXPConnect* xpc = nsXPConnect::GetXPConnect(); - if(xpc) + nsCOMPtr iid = + dont_AddRef(static_cast(nsJSID::NewID(idString))); + PR_Free(idString); + if(iid) { - nsCOMPtr holder; - nsresult rv = xpc->WrapNative(cx, jsobj, - static_cast(iid), - NS_GET_IID(nsIJSID), - getter_AddRefs(holder)); - if(NS_SUCCEEDED(rv) && holder) + nsXPConnect* xpc = nsXPConnect::GetXPConnect(); + if(xpc) { - holder->GetJSObject(&obj); + 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); + } } } } return obj; } -// note: returned pointer is only valid while |obj| remains alive! -const nsID* +nsID* xpc_JSObjectToID(JSContext *cx, JSObject* obj) { + nsID* id = nsnull; if(!cx || !obj) return nsnull; @@ -1005,9 +1017,9 @@ xpc_JSObjectToID(JSContext *cx, JSObject* obj) wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID)))) { - return ((nsIJSID*)wrapper->GetIdentityObject())->GetID(); + ((nsIJSID*)wrapper->GetIdentityObject())->GetId(&id); } - return nsnull; + return id; } JSBool diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index b89523fe8a0..87ca5e24fc6 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& ID() const {return mID;} + const nsID* GetID() 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 const nsID* +extern 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 bd82608b98f..1369219b4f1 100644 --- a/js/src/xpconnect/src/xpcvariant.cpp +++ b/js/src/xpconnect/src/xpcvariant.cpp @@ -320,9 +320,14 @@ JSBool XPCVariant::InitializeData(XPCCallContext& ccx) // Let's see if it is a xpcJSID. - const nsID* id = xpc_JSObjectToID(ccx, jsobj); + // XXX It might be nice to have a non-allocing version of xpc_JSObjectToID. + nsID* id = xpc_JSObjectToID(ccx, jsobj); if(id) - return NS_SUCCEEDED(nsVariant::SetFromID(&mData, *id)); + { + JSBool success = NS_SUCCEEDED(nsVariant::SetFromID(&mData, *id)); + nsMemory::Free((char*)id); + return success; + } // 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 6cd71b87e03..9254c916f76 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; } - const nsID* iid; + nsID* iid; JSObject* obj; if(!JSVAL_IS_OBJECT(argv[0]) || (!(obj = JSVAL_TO_OBJECT(argv[0]))) || @@ -1971,6 +1971,7 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx, if(NS_FAILED(invokeResult)) { ThrowBadResult(invokeResult, ccx); + PR_Free(iid); return JS_FALSE; } @@ -1978,6 +1979,7 @@ 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/xpcom/glue/nsID.cpp b/xpcom/glue/nsID.cpp index 50f76a3af8f..a0f55bf8c79 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(NSID_LENGTH); // use PR_Malloc if this is to be freed with nsCRT::free + char *res = (char*)PR_Malloc(39); // use PR_Malloc if this is to be freed with nsCRT::free if (res != NULL) { - PR_snprintf(res, NSID_LENGTH, gIDFormat, + PR_snprintf(res, 39, 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,12 +138,3 @@ 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 070d81860cd..5744244dee8 100644 --- a/xpcom/glue/nsID.h +++ b/xpcom/glue/nsID.h @@ -44,8 +44,6 @@ #include "nscore.h" #endif -#define NSID_LENGTH 39 - /** * A "unique identifier". This is modeled after OSF DCE UUIDs. * @status FROZEN @@ -97,16 +95,8 @@ 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; //@} };