diff -r 000000000000 -r 6474c204b198 js/xpconnect/src/xpcObjectHelper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/js/xpconnect/src/xpcObjectHelper.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,134 @@ +/* -*- 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 +#include "nsAutoPtr.h" +#include "nsCOMPtr.h" +#include "nsIClassInfo.h" +#include "nsISupports.h" +#include "nsIXPCScriptable.h" +#include "nsWrapperCache.h" + +class xpcObjectHelper +{ +public: + 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 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 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 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 mCanonicalStrong; + nsISupports* mCanonical; + +private: + xpcObjectHelper(xpcObjectHelper& aOther) MOZ_DELETE; + + nsISupports* mObject; + nsWrapperCache* mCache; + nsCOMPtr mClassInfo; + nsRefPtr mXPCClassInfo; +}; + +#endif