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
) {
33 JSContext
* cx
= aGlobal
.Context();
35 nsTArray
<nsIID
> ifaces
;
37 JS::Rooted
<JS::Value
> iface(cx
);
38 for (uint32_t idx
= 0; idx
< aInterfaces
.Length(); ++idx
) {
39 iface
= aInterfaces
[idx
];
42 if (Maybe
<nsID
> id
= xpc::JSValue2ID(cx
, iface
)) {
43 ifaces
.AppendElement(*id
);
47 // Accept string valued names
48 if (iface
.isString()) {
49 JS::UniqueChars name
= JS_EncodeStringToLatin1(cx
, iface
.toString());
51 const nsXPTInterfaceInfo
* iinfo
= nsXPTInterfaceInfo::ByName(name
.get());
53 ifaces
.AppendElement(iinfo
->IID());
58 // NOTE: We ignore unknown interfaces here because in some cases we try to
59 // pass them in to support multiple platforms.
62 MOZ_ASSERT(!ifaces
.Contains(NS_GET_IID(nsISupports
), CompareIIDs
));
63 ifaces
.AppendElement(NS_GET_IID(nsISupports
));
65 ifaces
.Sort(CompareIIDs
);
67 return new MozQueryInterface(std::move(ifaces
));
70 bool MozQueryInterface::QueriesTo(const nsIID
& aIID
) const {
71 return mInterfaces
.ContainsSorted(aIID
, CompareIIDs
);
74 void MozQueryInterface::LegacyCall(JSContext
* cx
, JS::Handle
<JS::Value
> thisv
,
75 JS::Handle
<JS::Value
> aIID
,
76 JS::MutableHandle
<JS::Value
> aResult
,
77 ErrorResult
& aRv
) const {
78 Maybe
<nsID
> id
= xpc::JSValue2ID(cx
, aIID
);
79 if (id
&& QueriesTo(*id
)) {
82 aRv
.Throw(NS_ERROR_NO_INTERFACE
);
86 bool MozQueryInterface::WrapObject(JSContext
* aCx
,
87 JS::Handle
<JSObject
*> aGivenProto
,
88 JS::MutableHandle
<JSObject
*> aReflector
) {
89 return MozQueryInterface_Binding::Wrap(aCx
, this, aGivenProto
, aReflector
);
92 } // namespace mozilla::dom