1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ChromeUtils.h"
8 #include "MozQueryInterface.h"
15 #include "mozilla/ErrorResult.h"
16 #include "xpcpublic.h"
18 namespace mozilla::dom
{
20 constexpr size_t IID_SIZE
= sizeof(nsIID
);
24 "Size of nsID struct changed. Please ensure this code is still valid.");
26 static int CompareIIDs(const nsIID
& aA
, const nsIID
& aB
) {
27 return memcmp((void*)&aA
.m0
, (void*)&aB
.m0
, IID_SIZE
);
31 MozQueryInterface
* ChromeUtils::GenerateQI(
32 const GlobalObject
& aGlobal
, const Sequence
<JS::Value
>& aInterfaces
,
34 JSContext
* cx
= aGlobal
.Context();
36 nsTArray
<nsIID
> ifaces
;
38 JS::RootedValue
iface(cx
);
39 for (uint32_t idx
= 0; idx
< aInterfaces
.Length(); ++idx
) {
40 iface
= aInterfaces
[idx
];
43 if (Maybe
<nsID
> id
= xpc::JSValue2ID(cx
, iface
)) {
44 ifaces
.AppendElement(*id
);
48 // Accept string valued names
49 if (iface
.isString()) {
50 JS::UniqueChars name
= JS_EncodeStringToLatin1(cx
, iface
.toString());
52 const nsXPTInterfaceInfo
* iinfo
= nsXPTInterfaceInfo::ByName(name
.get());
54 ifaces
.AppendElement(iinfo
->IID());
59 // NOTE: We ignore unknown interfaces here because in some cases we try to
60 // pass them in to support multiple platforms.
63 MOZ_ASSERT(!ifaces
.Contains(NS_GET_IID(nsISupports
), CompareIIDs
));
64 ifaces
.AppendElement(NS_GET_IID(nsISupports
));
66 ifaces
.Sort(CompareIIDs
);
68 return new MozQueryInterface(std::move(ifaces
));
71 bool MozQueryInterface::QueriesTo(const nsIID
& aIID
) const {
72 return mInterfaces
.ContainsSorted(aIID
, CompareIIDs
);
75 void MozQueryInterface::LegacyCall(JSContext
* cx
, JS::Handle
<JS::Value
> thisv
,
76 JS::Handle
<JS::Value
> aIID
,
77 JS::MutableHandle
<JS::Value
> aResult
,
78 ErrorResult
& aRv
) const {
79 Maybe
<nsID
> id
= xpc::JSValue2ID(cx
, aIID
);
80 if (id
&& QueriesTo(*id
)) {
83 aRv
.Throw(NS_ERROR_NO_INTERFACE
);
87 bool MozQueryInterface::WrapObject(JSContext
* aCx
,
88 JS::Handle
<JSObject
*> aGivenProto
,
89 JS::MutableHandle
<JSObject
*> aReflector
) {
90 return MozQueryInterface_Binding::Wrap(aCx
, this, aGivenProto
, aReflector
);
93 } // namespace mozilla::dom