// static XPCJSRuntime* XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect, nsIJSRuntimeService* aJSRuntimeService) { NS_PRECONDITION(aXPConnect,"bad param"); NS_PRECONDITION(aJSRuntimeService,"bad param"); XPCJSRuntime* self; self = new XPCJSRuntime(aXPConnect, aJSRuntimeService); if(self && self->GetJSRuntime() && self->GetContextMap() && self->GetWrappedJSMap() && self->GetWrappedJSClassMap() && self->GetIID2NativeInterfaceMap() && self->GetClassInfo2NativeSetMap() && self->GetNativeSetMap() && self->GetThisTranslatorMap() && self->GetNativeScriptableSharedMap() && self->GetDyingWrappedNativeProtoMap() && self->GetExplicitNativeWrapperMap() && self->GetMapLock()) { return self; } delete self; return nsnull; }
// static void XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo* classInfo) { XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap(); if (map) map->Remove(classInfo); }
// static void XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo* classInfo) { XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap(); if (map) { // scoped lock XPCAutoLock lock(rt->GetMapLock()); map->Remove(classInfo); } }
// static XPCNativeSet* XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, nsIClassInfo* classInfo) { AutoMarkingNativeSetPtr set(ccx); XPCJSRuntime* rt = ccx.GetRuntime(); ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap(); if (!map) return nsnull; { // scoped lock XPCAutoLock lock(rt->GetMapLock()); set = map->Find(classInfo); } if (set) return set; nsIID** iidArray = nsnull; AutoMarkingNativeInterfacePtrArrayPtr interfaceArray(ccx); PRUint32 iidCount = 0; if (NS_FAILED(classInfo->GetInterfaces(&iidCount, &iidArray))) { // Note: I'm making it OK for this call to fail so that one can add // nsIClassInfo to classes implemented in script without requiring this // method to be implemented. // Make sure these are set correctly... iidArray = nsnull; iidCount = 0; } NS_ASSERTION((iidCount && iidArray) || !(iidCount || iidArray), "GetInterfaces returned bad array"); // !!! from here on we only exit through the 'out' label !!! if (iidCount) { AutoMarkingNativeInterfacePtrArrayPtr arr(ccx, new XPCNativeInterface*[iidCount], iidCount, true); if (!arr) goto out; interfaceArray = arr; XPCNativeInterface** currentInterface = interfaceArray; nsIID** currentIID = iidArray; PRUint16 interfaceCount = 0; for (PRUint32 i = 0; i < iidCount; i++) { nsIID* iid = *(currentIID++); if (!iid) { NS_ERROR("Null found in classinfo interface list"); continue; } XPCNativeInterface* iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); if (!iface) { // XXX warn here continue; } *(currentInterface++) = iface; interfaceCount++; } if (interfaceCount) { set = NewInstance(ccx, interfaceArray, interfaceCount); if (set) { NativeSetMap* map2 = rt->GetNativeSetMap(); if (!map2) goto out; XPCNativeSetKey key(set, nsnull, 0); { // scoped lock XPCAutoLock lock(rt->GetMapLock()); XPCNativeSet* set2 = map2->Add(&key, set); if (!set2) { NS_ERROR("failed to add our set!"); DestroyInstance(set); set = nsnull; goto out; } if (set2 != set) { DestroyInstance(set); set = set2; } } } } else set = GetNewOrUsed(ccx, &NS_GET_IID(nsISupports)); } else set = GetNewOrUsed(ccx, &NS_GET_IID(nsISupports)); if (set) { // scoped lock XPCAutoLock lock(rt->GetMapLock()); #ifdef DEBUG XPCNativeSet* set2 = #endif map->Add(classInfo, set); NS_ASSERTION(set2, "failed to add our set!"); NS_ASSERTION(set2 == set, "hashtables inconsistent!"); } out: if (iidArray) NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iidCount, iidArray); if (interfaceArray) delete [] interfaceArray.get(); return set; }