michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim: set ts=8 sts=4 et sw=4 tw=99: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozJSComponentLoader_h michael@0: #define mozJSComponentLoader_h michael@0: michael@0: #include "mozilla/MemoryReporting.h" michael@0: #include "mozilla/ModuleLoader.h" michael@0: #include "nsISupports.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsIURI.h" michael@0: #include "xpcIJSModuleLoader.h" michael@0: #include "nsClassHashtable.h" michael@0: #include "nsCxPusher.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "jsapi.h" michael@0: michael@0: #include "xpcIJSGetFactory.h" michael@0: michael@0: class nsIFile; michael@0: class nsIJSRuntimeService; michael@0: class nsIPrincipal; michael@0: class nsIXPConnectJSObjectHolder; michael@0: michael@0: /* 6bd13476-1dd2-11b2-bbef-f0ccb5fa64b6 (thanks, mozbot) */ michael@0: michael@0: #define MOZJSCOMPONENTLOADER_CID \ michael@0: {0x6bd13476, 0x1dd2, 0x11b2, \ michael@0: { 0xbb, 0xef, 0xf0, 0xcc, 0xb5, 0xfa, 0x64, 0xb6 }} michael@0: #define MOZJSCOMPONENTLOADER_CONTRACTID "@mozilla.org/moz/jsloader;1" michael@0: michael@0: class JSCLContextHelper; michael@0: michael@0: class mozJSComponentLoader : public mozilla::ModuleLoader, michael@0: public xpcIJSModuleLoader, michael@0: public nsIObserver michael@0: { michael@0: friend class JSCLContextHelper; michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_XPCIJSMODULELOADER michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: mozJSComponentLoader(); michael@0: virtual ~mozJSComponentLoader(); michael@0: michael@0: // ModuleLoader michael@0: const mozilla::Module* LoadModule(mozilla::FileLocation &aFile); michael@0: michael@0: nsresult FindTargetObject(JSContext* aCx, michael@0: JS::MutableHandleObject aTargetObject); michael@0: michael@0: static mozJSComponentLoader* Get() { return sSelf; } michael@0: michael@0: void NoteSubScript(JS::HandleScript aScript, JS::HandleObject aThisObject); michael@0: michael@0: size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); michael@0: michael@0: protected: michael@0: static mozJSComponentLoader* sSelf; michael@0: michael@0: nsresult ReallyInit(); michael@0: void UnloadModules(); michael@0: michael@0: JSObject* PrepareObjectForLocation(JSCLContextHelper& aCx, michael@0: nsIFile* aComponentFile, michael@0: nsIURI *aComponent, michael@0: bool aReuseLoaderGlobal, michael@0: bool *aRealFile); michael@0: michael@0: nsresult ObjectForLocation(nsIFile* aComponentFile, michael@0: nsIURI *aComponent, michael@0: JS::MutableHandleObject aObject, michael@0: JS::MutableHandleScript aTableScript, michael@0: char **location, michael@0: bool aCatchException, michael@0: JS::MutableHandleValue aException); michael@0: michael@0: nsresult ImportInto(const nsACString &aLocation, michael@0: JS::HandleObject targetObj, michael@0: JSContext *callercx, michael@0: JS::MutableHandleObject vp); michael@0: michael@0: nsCOMPtr mCompMgr; michael@0: nsCOMPtr mRuntimeService; michael@0: nsCOMPtr mSystemPrincipal; michael@0: nsCOMPtr mLoaderGlobal; michael@0: JSRuntime *mRuntime; michael@0: JSContext *mContext; michael@0: michael@0: class ModuleEntry : public mozilla::Module michael@0: { michael@0: public: michael@0: ModuleEntry(JSContext* aCx) michael@0: : mozilla::Module(), obj(aCx, nullptr), thisObjectKey(aCx, nullptr) michael@0: { michael@0: mVersion = mozilla::Module::kVersion; michael@0: mCIDs = nullptr; michael@0: mContractIDs = nullptr; michael@0: mCategoryEntries = nullptr; michael@0: getFactoryProc = GetFactory; michael@0: loadProc = nullptr; michael@0: unloadProc = nullptr; michael@0: michael@0: location = nullptr; michael@0: } michael@0: michael@0: ~ModuleEntry() { michael@0: Clear(); michael@0: } michael@0: michael@0: void Clear() { michael@0: getfactoryobj = nullptr; michael@0: michael@0: if (obj) { michael@0: mozilla::AutoJSContext cx; michael@0: JSAutoCompartment ac(cx, obj); michael@0: michael@0: JS_SetAllNonReservedSlotsToUndefined(cx, obj); michael@0: obj = nullptr; michael@0: thisObjectKey = nullptr; michael@0: } michael@0: michael@0: if (location) michael@0: NS_Free(location); michael@0: michael@0: obj = nullptr; michael@0: thisObjectKey = nullptr; michael@0: location = nullptr; michael@0: } michael@0: michael@0: size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; michael@0: michael@0: static already_AddRefed GetFactory(const mozilla::Module& module, michael@0: const mozilla::Module::CIDEntry& entry); michael@0: michael@0: nsCOMPtr getfactoryobj; michael@0: JS::PersistentRootedObject obj; michael@0: JS::PersistentRootedScript thisObjectKey; michael@0: char *location; michael@0: }; michael@0: michael@0: friend class ModuleEntry; michael@0: michael@0: static size_t DataEntrySizeOfExcludingThis(const nsACString& aKey, ModuleEntry* const& aData, michael@0: mozilla::MallocSizeOf aMallocSizeOf, void* arg); michael@0: static size_t ClassEntrySizeOfExcludingThis(const nsACString& aKey, michael@0: const nsAutoPtr& aData, michael@0: mozilla::MallocSizeOf aMallocSizeOf, void* arg); michael@0: michael@0: // Modules are intentionally leaked, but still cleared. michael@0: static PLDHashOperator ClearModules(const nsACString& key, ModuleEntry*& entry, void* cx); michael@0: nsDataHashtable mModules; michael@0: michael@0: nsClassHashtable mImports; michael@0: nsDataHashtable mInProgressImports; michael@0: nsDataHashtable, JSObject*> mThisObjects; michael@0: michael@0: bool mInitialized; michael@0: bool mReuseLoaderGlobal; michael@0: }; michael@0: michael@0: #endif