/* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */ NS_IMETHODIMP nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const jsval &val, bool *bp, bool *_retval) { *bp = false; nsresult rv = NS_OK; if (!JSVAL_IS_PRIMITIVE(val)) { // we have a JSObject JSObject* obj = JSVAL_TO_OBJECT(val); NS_ASSERTION(obj, "when is an object not an object?"); // is this really a native xpcom object with a wrapper? JSObject* obj2; XPCWrappedNative* other_wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, nsnull, &obj2); if (!other_wrapper && !obj2) return NS_OK; nsIClassInfo* ci = other_wrapper ? other_wrapper->GetClassInfo() : GetSlimWrapperProto(obj2)->GetClassInfo(); // We consider CID equality to be the thing that matters here. // This is perhaps debatable. if (ci) { nsID cid; if (NS_SUCCEEDED(ci->GetClassIDNoAlloc(&cid))) *bp = cid.Equals(mDetails.ID()); } } return rv; }
/* PRBool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out PRBool bp); */ NS_IMETHODIMP nsJSIID::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const jsval &val, PRBool *bp, PRBool *_retval) { *bp = JS_FALSE; nsresult rv = NS_OK; if(!JSVAL_IS_PRIMITIVE(val)) { // we have a JSObject JSObject* obj = JSVAL_TO_OBJECT(val); NS_ASSERTION(obj, "when is an object not an object?"); // is this really a native xpcom object with a wrapper? const nsIID* iid; mInfo->GetIIDShared(&iid); if(IS_SLIM_WRAPPER(obj)) { XPCWrappedNativeProto* proto = GetSlimWrapperProto(obj); if(proto->GetSet()->HasInterfaceWithAncestor(iid)) { *bp = JS_TRUE; return NS_OK; } #ifdef DEBUG_slimwrappers char foo[NSID_LENGTH]; iid->ToProvidedString(foo); SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, foo); #endif if(!MorphSlimWrapper(cx, obj)) return NS_ERROR_FAILURE; } XPCWrappedNative* other_wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj); if(!other_wrapper) return NS_OK; // We'll trust the interface set of the wrapper if this is known // to be an interface that the objects *expects* to be able to // handle. if(other_wrapper->HasInterfaceNoQI(*iid)) { *bp = JS_TRUE; return NS_OK; } // Otherwise, we'll end up Querying the native object to be sure. XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); if(iface && other_wrapper->FindTearOff(ccx, iface)) *bp = JS_TRUE; } return rv; }
/* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */ NS_IMETHODIMP nsJSIID::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const jsval &val, bool *bp, bool *_retval) { *bp = false; nsresult rv = NS_OK; if (!JSVAL_IS_PRIMITIVE(val)) { // we have a JSObject JSObject* obj = JSVAL_TO_OBJECT(val); NS_ASSERTION(obj, "when is an object not an object?"); // is this really a native xpcom object with a wrapper? const nsIID* iid; mInfo->GetIIDShared(&iid); if (IS_SLIM_WRAPPER(obj)) { XPCWrappedNativeProto* proto = GetSlimWrapperProto(obj); if (proto->GetSet()->HasInterfaceWithAncestor(iid)) { *bp = true; return NS_OK; } #ifdef DEBUG_slimwrappers char foo[NSID_LENGTH]; iid->ToProvidedString(foo); SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, foo); #endif if (!MorphSlimWrapper(cx, obj)) return NS_ERROR_FAILURE; } nsISupports *identity; if (mozilla::dom::binding::instanceIsProxy(obj)) { identity = static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate()); } else if (mozilla::dom::bindings::IsDOMClass(js::GetObjectJSClass(obj))) { NS_ASSERTION(mozilla::dom::bindings::DOMJSClass::FromJSClass( js::GetObjectJSClass(obj))->mDOMObjectIsISupports, "This only works on nsISupports classes!"); identity = mozilla::dom::bindings::UnwrapDOMObject<nsISupports>(obj, js::GetObjectJSClass(obj)); } else { identity = nsnull; } if (identity) { nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(identity); XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeSetPtr set(ccx); set = XPCNativeSet::GetNewOrUsed(ccx, ci); if (!set) return NS_ERROR_FAILURE; *bp = set->HasInterfaceWithAncestor(iid); return NS_OK; } XPCWrappedNative* other_wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj); if (!other_wrapper) return NS_OK; // We'll trust the interface set of the wrapper if this is known // to be an interface that the objects *expects* to be able to // handle. if (other_wrapper->HasInterfaceNoQI(*iid)) { *bp = true; return NS_OK; } // Otherwise, we'll end up Querying the native object to be sure. XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); nsresult findResult = NS_OK; if (iface && other_wrapper->FindTearOff(ccx, iface, false, &findResult)) *bp = true; if (NS_FAILED(findResult) && findResult != NS_ERROR_NO_INTERFACE) rv = findResult; } return rv; }