tenfourfox/js/xpconnect/src/xpcObjectHelper.h

139 lines
3.7 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef xpcObjectHelper_h
#define xpcObjectHelper_h
// Including 'windows.h' will #define GetClassInfo to something else.
#ifdef XP_WIN
#ifdef GetClassInfo
#undef GetClassInfo
#endif
#endif
#include "mozilla/Attributes.h"
#include <stdint.h>
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsIClassInfo.h"
#include "nsISupports.h"
#include "nsIXPCScriptable.h"
#include "nsWrapperCache.h"
class xpcObjectHelper
{
public:
explicit xpcObjectHelper(nsISupports* aObject, nsWrapperCache* aCache = nullptr)
: mCanonical(nullptr)
, mObject(aObject)
, mCache(aCache)
{
if (!mCache) {
if (aObject)
CallQueryInterface(aObject, &mCache);
else
mCache = nullptr;
}
}
nsISupports* Object()
{
return mObject;
}
nsISupports* GetCanonical()
{
if (!mCanonical) {
mCanonicalStrong = do_QueryInterface(mObject);
mCanonical = mCanonicalStrong;
}
return mCanonical;
}
already_AddRefed<nsISupports> forgetCanonical()
{
MOZ_ASSERT(mCanonical, "Huh, no canonical to forget?");
if (!mCanonicalStrong)
mCanonicalStrong = mCanonical;
mCanonical = nullptr;
return mCanonicalStrong.forget();
}
nsIClassInfo* GetClassInfo()
{
if (mXPCClassInfo)
return mXPCClassInfo;
if (!mClassInfo)
mClassInfo = do_QueryInterface(mObject);
return mClassInfo;
}
nsXPCClassInfo* GetXPCClassInfo()
{
if (!mXPCClassInfo) {
CallQueryInterface(mObject, getter_AddRefs(mXPCClassInfo));
}
return mXPCClassInfo;
}
already_AddRefed<nsXPCClassInfo> forgetXPCClassInfo()
{
GetXPCClassInfo();
return mXPCClassInfo.forget();
}
// We assert that we can reach an nsIXPCScriptable somehow.
uint32_t GetScriptableFlags()
{
// Try getting an nsXPCClassInfo - this handles DOM scriptable helpers.
nsCOMPtr<nsIXPCScriptable> sinfo = GetXPCClassInfo();
// If that didn't work, try just QI-ing. This handles BackstagePass.
if (!sinfo)
sinfo = do_QueryInterface(GetCanonical());
// We should have something by now.
MOZ_ASSERT(sinfo);
// Grab the flags.
return sinfo->GetScriptableFlags();
}
nsWrapperCache* GetWrapperCache()
{
return mCache;
}
protected:
xpcObjectHelper(nsISupports* aObject, nsISupports* aCanonical,
nsWrapperCache* aCache)
: mCanonical(aCanonical)
, mObject(aObject)
, mCache(aCache)
{
if (!mCache && aObject)
CallQueryInterface(aObject, &mCache);
}
nsCOMPtr<nsISupports> mCanonicalStrong;
nsISupports* MOZ_UNSAFE_REF("xpcObjectHelper has been specifically optimized "
"to avoid unnecessary AddRefs and Releases. "
"(see bug 565742)") mCanonical;
private:
xpcObjectHelper(xpcObjectHelper& aOther) = delete;
nsISupports* MOZ_UNSAFE_REF("xpcObjectHelper has been specifically optimized "
"to avoid unnecessary AddRefs and Releases. "
"(see bug 565742)") mObject;
nsWrapperCache* mCache;
nsCOMPtr<nsIClassInfo> mClassInfo;
RefPtr<nsXPCClassInfo> mXPCClassInfo;
};
#endif