// static XPCWrappedNativeProto* XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope, nsIClassInfo* classInfo, const XPCNativeScriptableCreateInfo* scriptableCreateInfo, bool callPostCreatePrototype) { AutoJSContext cx; MOZ_ASSERT(scope, "bad param"); MOZ_ASSERT(classInfo, "bad param"); AutoMarkingWrappedNativeProtoPtr proto(cx); ClassInfo2WrappedNativeProtoMap* map = nullptr; map = scope->GetWrappedNativeProtoMap(); proto = map->Find(classInfo); if (proto) return proto; RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(classInfo); if (!set) return nullptr; proto = new XPCWrappedNativeProto(scope, classInfo, set.forget()); if (!proto || !proto->Init(scriptableCreateInfo, callPostCreatePrototype)) { delete proto.get(); return nullptr; } map->Add(classInfo, proto); return proto; }
void XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj) { MOZ_ASSERT(obj == mJSProtoObject, "huh?"); // Only remove this proto from the map if it is the one in the map. ClassInfo2WrappedNativeProtoMap* map = GetScope()->GetWrappedNativeProtoMap(); if (map->Find(mClassInfo) == this) map->Remove(mClassInfo); GetContext()->GetDyingWrappedNativeProtoMap()->Add(this); mJSProtoObject.finalize(js::CastToJSFreeOp(fop)->runtime()); }
// static XPCWrappedNativeProto* XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope, nsIClassInfo* classInfo, const XPCNativeScriptableCreateInfo* scriptableCreateInfo, QITableEntry* offsets, bool callPostCreatePrototype) { AutoJSContext cx; NS_ASSERTION(scope, "bad param"); NS_ASSERTION(classInfo, "bad param"); AutoMarkingWrappedNativeProtoPtr proto(cx); ClassInfo2WrappedNativeProtoMap* map = nullptr; XPCLock* lock = nullptr; uint32_t ciFlags; if (NS_FAILED(classInfo->GetFlags(&ciFlags))) ciFlags = 0; JSBool mainThreadOnly = !!(ciFlags & nsIClassInfo::MAIN_THREAD_ONLY); map = scope->GetWrappedNativeProtoMap(mainThreadOnly); lock = mainThreadOnly ? nullptr : scope->GetRuntime()->GetMapLock(); { // scoped lock XPCAutoLock al(lock); proto = map->Find(classInfo); if (proto) return proto; } AutoMarkingNativeSetPtr set(cx); set = XPCNativeSet::GetNewOrUsed(classInfo); if (!set) return nullptr; proto = new XPCWrappedNativeProto(scope, classInfo, ciFlags, set, offsets); if (!proto || !proto->Init(scriptableCreateInfo, callPostCreatePrototype)) { delete proto.get(); return nullptr; } { // scoped lock XPCAutoLock al(lock); map->Add(classInfo, proto); } return proto; }
void XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp *fop, JSObject *obj) { NS_ASSERTION(obj == mJSProtoObject, "huh?"); // Map locking is not necessary since we are running gc. // Only remove this proto from the map if it is the one in the map. ClassInfo2WrappedNativeProtoMap* map = GetScope()->GetWrappedNativeProtoMap(ClassIsMainThreadOnly()); if (map->Find(mClassInfo) == this) map->Remove(mClassInfo); GetRuntime()->GetDetachedWrappedNativeProtoMap()->Remove(this); GetRuntime()->GetDyingWrappedNativeProtoMap()->Add(this); mJSProtoObject.finalize(js::CastToJSFreeOp(fop)->runtime()); }
void XPCWrappedNativeProto::JSProtoObjectFinalized(JSContext *cx, JSObject *obj) { NS_ASSERTION(obj == mJSProtoObject, "huh?"); // Map locking is not necessary since we are running gc. if(IsShared()) { // Only remove this proto from the map if it is the one in the map. ClassInfo2WrappedNativeProtoMap* map = GetScope()->GetWrappedNativeProtoMap(ClassIsMainThreadOnly()); if(map->Find(mClassInfo) == this) map->Remove(mClassInfo); } GetRuntime()->GetDetachedWrappedNativeProtoMap()->Remove(this); GetRuntime()->GetDyingWrappedNativeProtoMap()->Add(this); mJSProtoObject = nsnull; }
// static XPCWrappedNativeProto* XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope, nsIClassInfo* classInfo, const XPCNativeScriptableCreateInfo* scriptableCreateInfo, bool callPostCreatePrototype) { AutoJSContext cx; MOZ_ASSERT(scope, "bad param"); MOZ_ASSERT(classInfo, "bad param"); AutoMarkingWrappedNativeProtoPtr proto(cx); ClassInfo2WrappedNativeProtoMap* map = nullptr; uint32_t ciFlags; if (NS_FAILED(classInfo->GetFlags(&ciFlags))) ciFlags = 0; map = scope->GetWrappedNativeProtoMap(); proto = map->Find(classInfo); if (proto) return proto; AutoMarkingNativeSetPtr set(cx); set = XPCNativeSet::GetNewOrUsed(classInfo); if (!set) return nullptr; proto = new XPCWrappedNativeProto(scope, classInfo, ciFlags, set); if (!proto || !proto->Init(scriptableCreateInfo, callPostCreatePrototype)) { delete proto.get(); return nullptr; } map->Add(classInfo, proto); return proto; }
// static XPCWrappedNativeProto* XPCWrappedNativeProto::GetNewOrUsed(XPCCallContext& ccx, XPCWrappedNativeScope* Scope, nsIClassInfo* ClassInfo, const XPCNativeScriptableCreateInfo* ScriptableCreateInfo, JSBool ForceNoSharing, JSBool isGlobal, QITableEntry* offsets) { NS_ASSERTION(Scope, "bad param"); NS_ASSERTION(ClassInfo, "bad param"); AutoMarkingWrappedNativeProtoPtr proto(ccx); ClassInfo2WrappedNativeProtoMap* map; XPCLock* lock; JSBool shared; JSUint32 ciFlags; if(NS_FAILED(ClassInfo->GetFlags(&ciFlags))) ciFlags = 0; if(ciFlags & XPC_PROTO_DONT_SHARE) { NS_ERROR("reserved flag set!"); ciFlags &= ~XPC_PROTO_DONT_SHARE; } if(ForceNoSharing || (ciFlags & nsIClassInfo::PLUGIN_OBJECT) || (ScriptableCreateInfo && ScriptableCreateInfo->GetFlags().DontSharePrototype())) { ciFlags |= XPC_PROTO_DONT_SHARE; shared = JS_FALSE; } else { shared = JS_TRUE; } if(shared) { JSBool mainThreadOnly = !!(ciFlags & nsIClassInfo::MAIN_THREAD_ONLY); map = Scope->GetWrappedNativeProtoMap(mainThreadOnly); lock = mainThreadOnly ? nsnull : Scope->GetRuntime()->GetMapLock(); { // scoped lock XPCAutoLock al(lock); proto = map->Find(ClassInfo); if(proto) return proto; } } AutoMarkingNativeSetPtr set(ccx); set = XPCNativeSet::GetNewOrUsed(ccx, ClassInfo); if(!set) return nsnull; proto = new XPCWrappedNativeProto(Scope, ClassInfo, ciFlags, set, offsets); if(!proto || !proto->Init(ccx, isGlobal, ScriptableCreateInfo)) { delete proto.get(); return nsnull; } if(shared) { // scoped lock XPCAutoLock al(lock); map->Add(ClassInfo, proto); } return proto; }