summaryrefslogtreecommitdiffstats
path: root/js/xpconnect/loader/mozJSComponentLoader.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/xpconnect/loader/mozJSComponentLoader.h')
-rw-r--r--js/xpconnect/loader/mozJSComponentLoader.h194
1 files changed, 194 insertions, 0 deletions
diff --git a/js/xpconnect/loader/mozJSComponentLoader.h b/js/xpconnect/loader/mozJSComponentLoader.h
new file mode 100644
index 0000000000..920fe5163d
--- /dev/null
+++ b/js/xpconnect/loader/mozJSComponentLoader.h
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 mozJSComponentLoader_h
+#define mozJSComponentLoader_h
+
+#include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/FileLocation.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/Module.h"
+#include "mozilla/StaticPtr.h"
+#include "mozilla/UniquePtr.h"
+#include "nsISupports.h"
+#include "nsIURI.h"
+#include "nsClassHashtable.h"
+#include "nsDataHashtable.h"
+#include "jsapi.h"
+
+#include "xpcIJSGetFactory.h"
+#include "xpcpublic.h"
+
+class nsIFile;
+class ComponentLoaderInfo;
+
+namespace mozilla {
+class ScriptPreloader;
+} // namespace mozilla
+
+#if defined(NIGHTLY_BUILD) || defined(MOZ_DEV_EDITION) || defined(DEBUG)
+# define STARTUP_RECORDER_ENABLED
+#endif
+
+class mozJSComponentLoader final {
+ public:
+ NS_INLINE_DECL_REFCOUNTING(mozJSComponentLoader);
+
+ void GetLoadedModules(nsTArray<nsCString>& aLoadedModules);
+ void GetLoadedComponents(nsTArray<nsCString>& aLoadedComponents);
+ nsresult GetModuleImportStack(const nsACString& aLocation,
+ nsACString& aRetval);
+ nsresult GetComponentLoadStack(const nsACString& aLocation,
+ nsACString& aRetval);
+
+ const mozilla::Module* LoadModule(mozilla::FileLocation& aFile);
+
+ void FindTargetObject(JSContext* aCx, JS::MutableHandleObject aTargetObject);
+
+ static void InitStatics();
+ static void Unload();
+ static void Shutdown();
+
+ static mozJSComponentLoader* Get() {
+ MOZ_ASSERT(sSelf, "Should have already created the component loader");
+ return sSelf;
+ }
+
+ nsresult ImportInto(const nsACString& aResourceURI,
+ JS::HandleValue aTargetObj, JSContext* aCx, uint8_t aArgc,
+ JS::MutableHandleValue aRetval);
+
+ nsresult Import(JSContext* aCx, const nsACString& aResourceURI,
+ JS::MutableHandleObject aModuleGlobal,
+ JS::MutableHandleObject aModuleExports,
+ bool aIgnoreExports = false);
+
+ nsresult Unload(const nsACString& aResourceURI);
+ nsresult IsModuleLoaded(const nsACString& aResourceURI, bool* aRetval);
+ bool IsLoaderGlobal(JSObject* aObj) { return mLoaderGlobal == aObj; }
+
+ size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
+
+ /**
+ * Temporary diagnostic function for startup crashes in bug 1403348:
+ *
+ * Annotate the crash report with the contents of the async shutdown
+ * module/component scripts.
+ */
+ nsresult AnnotateCrashReport();
+
+ protected:
+ mozJSComponentLoader();
+ ~mozJSComponentLoader();
+
+ friend class XPCJSRuntime;
+
+ private:
+ static mozilla::StaticRefPtr<mozJSComponentLoader> sSelf;
+
+ void UnloadModules();
+
+ void CreateLoaderGlobal(JSContext* aCx, const nsACString& aLocation,
+ JS::MutableHandleObject aGlobal);
+
+ JSObject* GetSharedGlobal(JSContext* aCx);
+
+ JSObject* PrepareObjectForLocation(JSContext* aCx, nsIFile* aComponentFile,
+ nsIURI* aComponent, bool* aRealFile);
+
+ nsresult ObjectForLocation(ComponentLoaderInfo& aInfo,
+ nsIFile* aComponentFile,
+ JS::MutableHandleObject aObject,
+ JS::MutableHandleScript aTableScript,
+ char** location, bool aCatchException,
+ JS::MutableHandleValue aException);
+
+ nsresult ImportInto(const nsACString& aLocation, JS::HandleObject targetObj,
+ JSContext* callercx, JS::MutableHandleObject vp);
+
+ nsCOMPtr<nsIComponentManager> mCompMgr;
+
+ class ModuleEntry : public mozilla::Module {
+ public:
+ explicit ModuleEntry(JS::RootingContext* aRootingCx)
+ : mozilla::Module(),
+ obj(aRootingCx),
+ exports(aRootingCx),
+ thisObjectKey(aRootingCx) {
+ mVersion = mozilla::Module::kVersion;
+ mCIDs = nullptr;
+ mContractIDs = nullptr;
+ mCategoryEntries = nullptr;
+ getFactoryProc = GetFactory;
+ loadProc = nullptr;
+ unloadProc = nullptr;
+
+ location = nullptr;
+ }
+
+ ~ModuleEntry() { Clear(); }
+
+ void Clear() {
+ getfactoryobj = nullptr;
+
+ if (obj) {
+ if (JS_HasExtensibleLexicalEnvironment(obj)) {
+ JS::RootedObject lexicalEnv(mozilla::dom::RootingCx(),
+ JS_ExtensibleLexicalEnvironment(obj));
+ JS_SetAllNonReservedSlotsToUndefined(lexicalEnv);
+ }
+ JS_SetAllNonReservedSlotsToUndefined(obj);
+ obj = nullptr;
+ thisObjectKey = nullptr;
+ }
+
+ if (location) {
+ free(location);
+ }
+
+ obj = nullptr;
+ thisObjectKey = nullptr;
+ location = nullptr;
+#ifdef STARTUP_RECORDER_ENABLED
+ importStack.Truncate();
+#endif
+ }
+
+ size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
+
+ static already_AddRefed<nsIFactory> GetFactory(
+ const mozilla::Module& module, const mozilla::Module::CIDEntry& entry);
+
+ nsCOMPtr<xpcIJSGetFactory> getfactoryobj;
+ JS::PersistentRootedObject obj;
+ JS::PersistentRootedObject exports;
+ JS::PersistentRootedScript thisObjectKey;
+ char* location;
+ nsCString resolvedURL;
+#ifdef STARTUP_RECORDER_ENABLED
+ nsCString importStack;
+#endif
+ };
+
+ nsresult ExtractExports(JSContext* aCx, ComponentLoaderInfo& aInfo,
+ ModuleEntry* aMod, JS::MutableHandleObject aExports);
+
+ // Modules are intentionally leaked, but still cleared.
+ nsDataHashtable<nsCStringHashKey, ModuleEntry*> mModules;
+
+ nsClassHashtable<nsCStringHashKey, ModuleEntry> mImports;
+ nsDataHashtable<nsCStringHashKey, ModuleEntry*> mInProgressImports;
+
+ // A map of on-disk file locations which are loaded as modules to the
+ // pre-resolved URIs they were loaded from. Used to prevent the same file
+ // from being loaded separately, from multiple URLs.
+ nsClassHashtable<nsCStringHashKey, nsCString> mLocations;
+
+ bool mInitialized;
+ JS::PersistentRooted<JSObject*> mLoaderGlobal;
+};
+
+#endif