diff --git a/dom/src/base/nsDOMClassInfo.cpp b/dom/src/base/nsDOMClassInfo.cpp index 47383c591fd..320bb955c32 100644 --- a/dom/src/base/nsDOMClassInfo.cpp +++ b/dom/src/base/nsDOMClassInfo.cpp @@ -1637,7 +1637,7 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx) // static nsresult nsDOMClassInfo::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native, - const nsIID& aIID, jsval *vp, + const nsIID* aIID, jsval *vp, nsIXPConnectJSObjectHolder **aHolder) { if (!native) { @@ -1682,7 +1682,7 @@ nsDOMClassInfo::ThrowJSException(JSContext *cx, nsresult aResult) jsval jv; nsCOMPtr holder; rv = WrapNative(cx, ::JS_GetGlobalObject(cx), exception, - NS_GET_IID(nsIException), &jv, getter_AddRefs(holder)); + &NS_GET_IID(nsIException), &jv, getter_AddRefs(holder)); if (NS_FAILED(rv) || JSVAL_IS_NULL(jv)) { break; } @@ -4485,8 +4485,7 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj, if (result) { jsval v; nsCOMPtr holder; - nsresult rv = WrapNative(cx, obj, result, NS_GET_IID(nsISupports), &v, - getter_AddRefs(holder)); + nsresult rv = WrapNative(cx, obj, result, &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, JS_FALSE); if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(jsstr), @@ -4680,7 +4679,7 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, nsCOMPtr holder; rv = WrapNative(cx, frameWin->GetGlobalJSObject(), frame, - NS_GET_IID(nsIDOMWindow), vp, + &NS_GET_IID(nsIDOMWindow), vp, getter_AddRefs(holder)); } @@ -4797,7 +4796,7 @@ nsWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && location, rv); nsCOMPtr holder; - rv = WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation), vp, + rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), vp, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -5052,8 +5051,8 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner, } nsCOMPtr holder; - rv = nsDOMGenericSH::WrapNative(cx, obj, native, NS_GET_IID(nsISupports), - rval, getter_AddRefs(holder)); + rv = nsDOMGenericSH::WrapNative(cx, obj, native, rval, + getter_AddRefs(holder)); return rv; } @@ -5519,7 +5518,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, nsCOMPtr holder; jsval v; - rv = WrapNative(cx, obj, constructor, NS_GET_IID(nsIDOMDOMConstructor), &v, + rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor), &v, getter_AddRefs(holder)); sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty; @@ -5581,7 +5580,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, nsCOMPtr holder; jsval v; - rv = WrapNative(cx, obj, constructor, NS_GET_IID(nsIDOMDOMConstructor), &v, + rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor), &v, getter_AddRefs(holder)); sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty; @@ -5796,7 +5795,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, jsval val; nsCOMPtr holder; - rv = WrapNative(cx, obj, constructor, NS_GET_IID(nsIDOMDOMConstructor), + rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor), &val, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -5844,8 +5843,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, scope = aWin->GetGlobalJSObject(); } - rv = WrapNative(cx, scope, native, NS_GET_IID(nsISupports), &prop_val, - getter_AddRefs(holder)); + rv = WrapNative(cx, scope, native, &prop_val, getter_AddRefs(holder)); } NS_ENSURE_SUCCESS(rv, rv); @@ -6136,7 +6134,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; rv = WrapNative(cx, wrapperObj, child_win, - NS_GET_IID(nsIDOMWindowInternal), &v, + &NS_GET_IID(nsIDOMWindowInternal), &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -6257,7 +6255,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; - rv = WrapNative(cx, scope, location, NS_GET_IID(nsIDOMLocation), &v, + rv = WrapNative(cx, scope, location, &NS_GET_IID(nsIDOMLocation), &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -6314,7 +6312,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; - rv = WrapNative(cx, obj, navigator, NS_GET_IID(nsIDOMNavigator), &v, + rv = WrapNative(cx, obj, navigator, &NS_GET_IID(nsIDOMNavigator), &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -6338,7 +6336,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; - rv = WrapNative(cx, obj, document, NS_GET_IID(nsIDOMDocument), &v, + rv = WrapNative(cx, obj, document, &NS_GET_IID(nsIDOMDocument), &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -6942,8 +6940,7 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj, jsval v; nsCOMPtr holder; - nsresult rv = WrapNative(cx, globalObj, native_parent, - NS_GET_IID(nsISupports), &v, + nsresult rv = WrapNative(cx, globalObj, native_parent, &v, getter_AddRefs(holder)); *parentObj = JSVAL_TO_OBJECT(v); @@ -7010,7 +7007,7 @@ nsNodeSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } nsCOMPtr holder; - nsresult rv = WrapNative(cx, obj, uri, NS_GET_IID(nsIURI), vp, + nsresult rv = WrapNative(cx, obj, uri, &NS_GET_IID(nsIURI), vp, getter_AddRefs(holder)); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } @@ -7021,7 +7018,7 @@ nsNodeSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, nsCOMPtr holder; nsresult rv = WrapNative(cx, obj, node->NodePrincipal(), - NS_GET_IID(nsIPrincipal), vp, + &NS_GET_IID(nsIPrincipal), vp, getter_AddRefs(holder)); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } @@ -7719,7 +7716,7 @@ nsArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_SUCCESS(rv, rv); if (array_item) { - rv = WrapNative(cx, obj, array_item, NS_GET_IID(nsISupports), vp); + rv = WrapNative(cx, obj, array_item, vp); NS_ENSURE_SUCCESS(rv, rv); rv = NS_SUCCESS_I_DID_SOMETHING; @@ -7753,8 +7750,7 @@ nsNodeListSH::PreCreate(nsISupports *nativeObj, JSContext *cx, jsval v; nsCOMPtr holder; - nsresult rv = WrapNative(cx, globalObj, native_parent, - NS_GET_IID(nsISupports), &v, + nsresult rv = WrapNative(cx, globalObj, native_parent, &v, getter_AddRefs(holder)); *parentObj = JSVAL_TO_OBJECT(v); @@ -7854,7 +7850,7 @@ nsNamedArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_SUCCESS(rv, rv); if (item) { - rv = WrapNative(cx, obj, item, NS_GET_IID(nsISupports), vp); + rv = WrapNative(cx, obj, item, vp); NS_ENSURE_SUCCESS(rv, rv); rv = NS_SUCCESS_I_DID_SOMETHING; @@ -7966,8 +7962,7 @@ nsContentListSH::PreCreate(nsISupports *nativeObj, JSContext *cx, jsval v; nsCOMPtr holder; - nsresult rv = WrapNative(cx, globalObj, native_parent, - NS_GET_IID(nsISupports), &v, + nsresult rv = WrapNative(cx, globalObj, native_parent, &v, getter_AddRefs(holder)); *parentObj = JSVAL_TO_OBJECT(v); @@ -8083,7 +8078,7 @@ nsDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; - rv = WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation), &v, + rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -8127,7 +8122,7 @@ nsDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE); nsCOMPtr holder; - nsresult rv = WrapNative(cx, obj, uri, NS_GET_IID(nsIURI), vp, + nsresult rv = WrapNative(cx, obj, uri, &NS_GET_IID(nsIURI), vp, getter_AddRefs(holder)); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; @@ -8159,7 +8154,7 @@ nsDocumentSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr holder; - rv = WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation), vp, + rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), vp, getter_AddRefs(holder)); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } @@ -8217,7 +8212,7 @@ nsDocumentSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval winVal; nsCOMPtr holder; - rv = WrapNative(cx, obj, win, NS_GET_IID(nsIDOMWindow), &winVal, + rv = WrapNative(cx, obj, win, &NS_GET_IID(nsIDOMWindow), &winVal, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -8336,7 +8331,7 @@ nsHTMLDocumentSH::DocumentOpen(JSContext *cx, JSObject *obj, uintN argc, } nsCOMPtr holder; - rv = WrapNative(cx, obj, retval, NS_GET_IID(nsIDOMDocument), rval, + rv = WrapNative(cx, obj, retval, &NS_GET_IID(nsIDOMDocument), rval, getter_AddRefs(holder)); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to wrap native!"); @@ -8411,8 +8406,7 @@ nsHTMLDocumentSH::GetDocumentAllNodeList(JSContext *cx, JSObject *obj, rv |= domdoc->GetElementsByTagName(NS_LITERAL_STRING("*"), nodeList); nsCOMPtr holder; - rv |= nsDOMClassInfo::WrapNative(cx, obj, *nodeList, - NS_GET_IID(nsISupports), &collection, + rv |= nsDOMClassInfo::WrapNative(cx, obj, *nodeList, &collection, getter_AddRefs(holder)); // ... and store it in our reserved slot. @@ -8499,7 +8493,7 @@ nsHTMLDocumentSH::DocumentAllGetProperty(JSContext *cx, JSObject *obj, } if (result) { - rv = WrapNative(cx, obj, result, NS_GET_IID(nsISupports), vp); + rv = WrapNative(cx, obj, result, vp); if (NS_FAILED(rv)) { nsDOMClassInfo::ThrowJSException(cx, rv); @@ -8771,8 +8765,7 @@ nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj, if (tags) { jsval v; nsCOMPtr holder; - nsresult rv = nsDOMClassInfo::WrapNative(cx, obj, tags, - NS_GET_IID(nsISupports), &v, + nsresult rv = nsDOMClassInfo::WrapNative(cx, obj, tags, &v, getter_AddRefs(holder)); if (NS_FAILED(rv)) { nsDOMClassInfo::ThrowJSException(cx, rv); @@ -8931,7 +8924,7 @@ nsHTMLDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper, NS_ENSURE_SUCCESS(rv, rv); if (result) { - rv = WrapNative(cx, obj, result, NS_GET_IID(nsISupports), vp); + rv = WrapNative(cx, obj, result, vp); if (NS_SUCCEEDED(rv)) { rv = NS_SUCCESS_I_DID_SOMETHING; } @@ -9071,7 +9064,7 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, if (result) { // Wrap result, result can be either an element or a list of // elements - nsresult rv = WrapNative(cx, obj, result, NS_GET_IID(nsISupports), vp); + nsresult rv = WrapNative(cx, obj, result, vp); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } } @@ -9083,7 +9076,7 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, form->GetElementAt(n, getter_AddRefs(control)); if (control) { - nsresult rv = WrapNative(cx, obj, control, NS_GET_IID(nsISupports), vp); + nsresult rv = WrapNative(cx, obj, control, vp); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } } @@ -9190,7 +9183,7 @@ nsHTMLSelectElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, options->Item(n, getter_AddRefs(node)); - rv = WrapNative(cx, obj, node, NS_GET_IID(nsIDOMNode), vp); + rv = WrapNative(cx, obj, node, &NS_GET_IID(nsIDOMNode), vp); if (NS_SUCCEEDED(rv)) { rv = NS_SUCCESS_I_DID_SOMETHING; } diff --git a/dom/src/base/nsDOMClassInfo.h b/dom/src/base/nsDOMClassInfo.h index cb5838a2769..cbeec2af03f 100644 --- a/dom/src/base/nsDOMClassInfo.h +++ b/dom/src/base/nsDOMClassInfo.h @@ -130,11 +130,22 @@ public: } static nsresult WrapNative(JSContext *cx, JSObject *scope, - nsISupports *native, const nsIID& aIID, + nsISupports *native, const nsIID* aIID, jsval *vp, // If non-null aHolder will keep the jsval alive // while there's a ref to it nsIXPConnectJSObjectHolder** aHolder = nsnull); + + // Same as the WrapNative above, but use this one if aIID is nsISupports' IID. + static nsresult WrapNative(JSContext *cx, JSObject *scope, + nsISupports *native, jsval *vp, + // If non-null aHolder will keep the jsval alive + // while there's a ref to it + nsIXPConnectJSObjectHolder** aHolder = nsnull) + { + return WrapNative(cx, scope, native, nsnull, vp, aHolder); + } + static nsresult ThrowJSException(JSContext *cx, nsresult aResult); static nsresult InitDOMJSClass(JSContext *cx, JSObject *obj); diff --git a/js/src/xpconnect/idl/nsIXPConnect.idl b/js/src/xpconnect/idl/nsIXPConnect.idl index 9f02cb5a5ad..24fdbf7ba91 100644 --- a/js/src/xpconnect/idl/nsIXPConnect.idl +++ b/js/src/xpconnect/idl/nsIXPConnect.idl @@ -471,12 +471,16 @@ interface nsIXPConnect : nsISupports * Same as wrapNative, but also returns the JSObject in aVal. C++ callers * can pass in null for the aHolder argument, but in that case they must * ensure that aVal is rooted. + * aIID may be null, it means the same as passing in + * &NS_GET_IID(nsISupports) but when passing in null certain shortcuts + * can be taken because we know without comparing IIDs that the caller is + * asking for an nsISupports wrapper. */ void wrapNativeToJSVal(in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, - in nsIIDRef aIID, + in nsIIDPtr aIID, out JSVal aVal, out nsIXPConnectJSObjectHolder aHolder); diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp index 3fa0ce72fc3..31518d42757 100644 --- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -1114,8 +1114,9 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext, nsresult rv; if(!XPCConvert::NativeInterface2JSObject(ccx, &v, getter_AddRefs(holder), - aCOMObj, &aIID, tempGlobal, - PR_FALSE, OBJ_IS_GLOBAL, &rv)) + aCOMObj, &aIID, nsnull, + tempGlobal, PR_FALSE, + OBJ_IS_GLOBAL, &rv)) return UnexpectedFailure(rv); NS_ASSERTION(NS_SUCCEEDED(rv) && holder, "Didn't wrap properly"); @@ -1187,15 +1188,15 @@ nsXPConnect::WrapNative(JSContext * aJSContext, NS_ASSERTION(aHolder, "bad param"); jsval v; - return WrapNativeToJSVal(aJSContext, aScope, aCOMObj, aIID, &v, aHolder); + return WrapNativeToJSVal(aJSContext, aScope, aCOMObj, &aIID, &v, aHolder); } -/* void wrapNativeToJSVal (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDRef aIID, out JSVal aVal, out nsIXPConnectJSObjectHolder aHolder); */ +/* void wrapNativeToJSVal (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDPtr aIID, out JSVal aVal, out nsIXPConnectJSObjectHolder aHolder); */ NS_IMETHODIMP nsXPConnect::WrapNativeToJSVal(JSContext * aJSContext, JSObject * aScope, nsISupports *aCOMObj, - const nsIID & aIID, + const nsIID * aIID, jsval *aVal, nsIXPConnectJSObjectHolder **aHolder) { @@ -1211,8 +1212,8 @@ nsXPConnect::WrapNativeToJSVal(JSContext * aJSContext, return UnexpectedFailure(NS_ERROR_FAILURE); nsresult rv; - if(!XPCConvert::NativeInterface2JSObject(ccx, aVal, aHolder, aCOMObj, &aIID, - aScope, PR_FALSE, + if(!XPCConvert::NativeInterface2JSObject(ccx, aVal, aHolder, aCOMObj, aIID, + nsnull, aScope, PR_FALSE, OBJ_IS_NOT_GLOBAL, &rv)) return rv; diff --git a/js/src/xpconnect/src/qsgen.py b/js/src/xpconnect/src/qsgen.py index 7c4a5775433..37f768945ff 100644 --- a/js/src/xpconnect/src/qsgen.py +++ b/js/src/xpconnect/src/qsgen.py @@ -330,10 +330,12 @@ def writeHeaderFile(filename, name): try: f.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n" "#ifndef " + headerMacro + "\n" - "#define " + headerMacro + "\n" + "#define " + headerMacro + "\n\n" "JSBool " + name + "_DefineQuickStubs(" "JSContext *cx, JSObject *proto, uintN flags, " - "PRUint32 count, const nsID **iids);\n" + "PRUint32 count, const nsID **iids);\n\n" + "void " + name + "_MarkInterfaces();\n\n" + "void " + name + "_ClearInterfaces();\n\n" "#endif\n") finally: f.close() @@ -598,8 +600,10 @@ def writeResultConv(f, type, paramNum, jsvalPtr, jsvalRef): % (paramNum, jsvalPtr)) return else: + f.write(" AutoMarkingNativeInterfacePtr resultiface(ccx, " + "%s_Interface(ccx));\n" % type.name) f.write(" return xpc_qsXPCOMObjectToJsval(ccx, result, " - "NS_GET_IID(%s), %s);\n" % (type.name, jsvalPtr)) + "resultiface, %s);\n" % jsvalPtr) return warn("Unable to convert result of type %s" % type.name) @@ -819,6 +823,32 @@ def hashIID(iid): uuid_re = re.compile(r'^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$') +def writeResultXPCInterfacesArray(f, conf, resulttypes): + f.write("// === XPCNativeInterface cache \n\n") + count = len(resulttypes) + if count > 0: + f.write("static XPCNativeInterface* interfaces[%d];\n\n" % count) + f.write("void %s_MarkInterfaces()\n" + "{\n" % conf.name) + if count > 0: + f.write(" for (PRUint32 i = 0; i < %d; ++i)\n" + " if (interfaces[i])\n" + " interfaces[i]->Mark();\n" % count) + f.write("}\n") + f.write("void %s_ClearInterfaces()\n" + "{\n" % conf.name) + if count > 0: + f.write(" memset(interfaces, 0, %d * " + "sizeof(XPCNativeInterface*));\n" % count) + f.write("}\n\n") + i = 0 + for type in resulttypes: + f.write("XPC_QS_DEFINE_XPCNATIVEINTERFACE_GETTER(%s, interfaces[%d])\n" + % (type, i)) + i += 1 + if count > 0: + f.write("\n\n") + def writeDefiner(f, conf, interfaces): f.write("// === Definer\n\n") @@ -937,31 +967,41 @@ def writeStubFile(filename, headerFilename, conf, interfaces): def includeType(type): type = unaliasType(type) if type.kind in ('builtin', 'native'): - return + return None file = conf.irregularFilenames.get(type.name, type.name) + '.h' if file not in filesIncluded: f.write('#include "%s"\n' % file) filesIncluded.add(file) + return type def writeIncludesForMember(member): assert member.kind in ('attribute', 'method') - includeType(member.realtype) + resulttype = includeType(member.realtype) if member.kind == 'method': for p in member.params: includeType(p.realtype) + return resulttype def writeIncludesForInterface(iface): assert iface.kind == 'interface' + resulttypes = [] for member in iface.stubMembers: - writeIncludesForMember(member) + resulttype = writeIncludesForMember(member) + if resulttype is not None and not isVariantType(resulttype): + resulttypes.append(resulttype.name) + includeType(iface) + return resulttypes + try: f.write(stubTopTemplate % os.path.basename(headerFilename)) N = 256 + resulttypes = [] for iface in interfaces: - writeIncludesForInterface(iface) + resulttypes.extend(writeIncludesForInterface(iface)) f.write("\n\n") + writeResultXPCInterfacesArray(f, conf, frozenset(resulttypes)) for iface in interfaces: writeStubsForInterface(f, iface) writeDefiner(f, conf, interfaces) diff --git a/js/src/xpconnect/src/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp index c36e520bbfb..7320df0d184 100644 --- a/js/src/xpconnect/src/xpcconvert.cpp +++ b/js/src/xpconnect/src/xpcconvert.cpp @@ -1054,12 +1054,12 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx, nsIXPConnectJSObjectHolder** dest, nsISupports* src, const nsID* iid, + XPCNativeInterface* interface, JSObject* scope, PRBool allowNativeWrapper, PRBool isGlobal, nsresult* pErr) { - NS_ASSERTION(iid, "bad param"); NS_ASSERTION(scope, "bad param"); *d = JSVAL_NULL; @@ -1090,7 +1090,13 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx, // verify that this wrapper is for the right interface nsCOMPtr wrapper; - src->QueryInterface(*iid, (void**)getter_AddRefs(wrapper)); + if(interface) + src->QueryInterface(*interface->GetIID(), + (void**)getter_AddRefs(wrapper)); + else if(iid) + src->QueryInterface(*iid, (void**)getter_AddRefs(wrapper)); + else + wrapper = do_QueryInterface(src); nsCOMPtr holder = do_QueryInterface(wrapper); JSObject* flat; @@ -1110,10 +1116,13 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx, if(!xpcscope) return JS_FALSE; - AutoMarkingNativeInterfacePtr iface(ccx); - iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); - if(!iface) - return JS_FALSE; + AutoMarkingNativeInterfacePtr iface(ccx, interface); + if(!iface && iid) + { + iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); + if(!iface) + return JS_FALSE; + } nsresult rv; XPCWrappedNative* wrapper; @@ -1128,7 +1137,8 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx, // rooted in that case). if(dest) strongWrapper = wrapper; - wrapper->FindTearOff(ccx, iface, JS_FALSE, &rv); + if(iface) + wrapper->FindTearOff(ccx, iface, JS_FALSE, &rv); } else { diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp index 6a22af73088..0cc838615c4 100644 --- a/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/js/src/xpconnect/src/xpcjsruntime.cpp @@ -41,6 +41,7 @@ /* Per JSRuntime object */ #include "xpcprivate.h" +#include "dom_quickstubs.h" /***************************************************************************/ @@ -605,6 +606,8 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status) self->mDetachedWrappedNativeProtoMap-> Enumerate(DetachedWrappedNativeProtoMarker, nsnull); + DOM_MarkInterfaces(); + // Mark the sets used in the call contexts. There is a small // chance that a wrapper's set will change *while* a call is // happening which uses that wrapper's old interfface set. So, @@ -1000,6 +1003,8 @@ XPCJSRuntime::~XPCJSRuntime() XPCConvert::RemoveXPCOMUCStringFinalizer(); + DOM_ClearInterfaces(); + if(mJSHolders.ops) { JS_DHashTableFinish(&mJSHolders); diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index 176b9696087..97bec464019 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -2765,6 +2765,7 @@ public: nsIXPConnectJSObjectHolder** dest, nsISupports* src, const nsID* iid, + XPCNativeInterface* interface, JSObject* scope, PRBool allowNativeWrapper, PRBool isGlobal, @@ -2779,9 +2780,9 @@ public: nsresult* pErr) { jsval v; - JSBool ok = NativeInterface2JSObject(ccx, &v, nsnull, src, iid, scope, - allowNativeWrapper, isGlobal, - pErr); + JSBool ok = NativeInterface2JSObject(ccx, &v, nsnull, src, iid, nsnull, + scope, allowNativeWrapper, + isGlobal, pErr); *dest = JSVAL_TO_OBJECT(v); return ok; } diff --git a/js/src/xpconnect/src/xpcquickstubs.cpp b/js/src/xpconnect/src/xpcquickstubs.cpp index c1abf018dd8..51c7b043dba 100644 --- a/js/src/xpconnect/src/xpcquickstubs.cpp +++ b/js/src/xpconnect/src/xpcquickstubs.cpp @@ -743,7 +743,7 @@ xpc_qsStringToJsval(JSContext *cx, const nsAString &str, jsval *rval) JSBool xpc_qsXPCOMObjectToJsval(XPCCallContext &ccx, nsISupports *p, - const nsIID &iid, jsval *rval) + XPCNativeInterface *interface, jsval *rval) { // From the T_INTERFACE case in XPCConvert::NativeData2JS. // This is one of the slowest things quick stubs do. @@ -751,14 +751,18 @@ xpc_qsXPCOMObjectToJsval(XPCCallContext &ccx, nsISupports *p, JSObject *scope = ccx.GetCurrentJSObject(); NS_ASSERTION(scope, "bad ccx"); + if(!interface) + return xpc_qsThrow(ccx, NS_ERROR_XPC_BAD_CONVERT_NATIVE); + // XXX The OBJ_IS_NOT_GLOBAL here is not really right. In // fact, this code is depending on the fact that the // global object will not have been collected, and // therefore this NativeInterface2JSObject will not end up // creating a new XPCNativeScriptableShared. nsresult rv; - if(!XPCConvert::NativeInterface2JSObject(ccx, rval, nsnull, p, &iid, scope, - PR_TRUE, OBJ_IS_NOT_GLOBAL, &rv)) + if(!XPCConvert::NativeInterface2JSObject(ccx, rval, nsnull, p, nsnull, + interface, scope, PR_TRUE, + OBJ_IS_NOT_GLOBAL, &rv)) { // I can't tell if NativeInterface2JSObject throws JS exceptions // or not. This is a sloppy stab at the right semantics; the diff --git a/js/src/xpconnect/src/xpcquickstubs.h b/js/src/xpconnect/src/xpcquickstubs.h index 99379b36dd7..73068ffa581 100644 --- a/js/src/xpconnect/src/xpcquickstubs.h +++ b/js/src/xpconnect/src/xpcquickstubs.h @@ -398,7 +398,7 @@ xpc_qsUnwrapArg(JSContext *cx, jsval v, T **ppArg) JSBool xpc_qsXPCOMObjectToJsval(XPCCallContext &ccx, nsISupports *p, - const nsIID &iid, + XPCNativeInterface *interface, jsval *rval); /** @@ -432,4 +432,14 @@ xpc_qsAssertContextOK(JSContext *cx); #define XPC_QS_ASSERT_CONTEXT_OK(cx) ((void) 0) #endif +#define XPC_QS_DEFINE_XPCNATIVEINTERFACE_GETTER(_iface, _iface_cache) \ +inline XPCNativeInterface* \ +_iface##_Interface(XPCCallContext& ccx) \ +{ \ + if(!(_iface_cache)) \ + (_iface_cache) = \ + XPCNativeInterface::GetNewOrUsed(ccx, &NS_GET_IID(_iface)); \ + return (_iface_cache); \ +} + #endif /* xpcquickstubs_h___ */ diff --git a/js/src/xpconnect/src/xpcwrappednative.cpp b/js/src/xpconnect/src/xpcwrappednative.cpp index 9509b75f2b7..929f4ce7d18 100644 --- a/js/src/xpconnect/src/xpcwrappednative.cpp +++ b/js/src/xpconnect/src/xpcwrappednative.cpp @@ -333,7 +333,7 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx, if(wrapper) { - if(!wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv)) + if(Interface && !wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv)) { NS_RELEASE(wrapper); NS_ASSERTION(NS_FAILED(rv), "returning NS_OK on failure"); @@ -356,7 +356,8 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx, // If we are making a wrapper for the nsIClassInfo interface then // We *don't* want to have it use the prototype meant for instances // of that class. - JSBool isClassInfo = Interface->GetIID()->Equals(NS_GET_IID(nsIClassInfo)); + JSBool isClassInfo = Interface && + Interface->GetIID()->Equals(NS_GET_IID(nsIClassInfo)); nsCOMPtr info; @@ -429,7 +430,7 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx, if(wrapper) { - if(!wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv)) + if(Interface && !wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv)) { NS_RELEASE(wrapper); NS_ASSERTION(NS_FAILED(rv), "returning NS_OK on failure"); @@ -488,7 +489,7 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx, return NS_ERROR_FAILURE; } - if(!wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv)) + if(Interface && !wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv)) { // Second reference will be released by the FlatJSObject's finializer. wrapper->Release(); @@ -636,7 +637,7 @@ XPCWrappedNative::GetUsedOnly(XPCCallContext& ccx, } nsresult rv; - if(!wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv)) + if(Interface && !wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv)) { NS_RELEASE(wrapper); NS_ASSERTION(NS_FAILED(rv), "returning NS_OK on failure");