Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim: set ts=8 sts=4 et sw=4 tw=99: */
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/. */
6 :
7 : #ifndef mozJSComponentLoader_h
8 : #define mozJSComponentLoader_h
9 :
10 : #include "mozilla/dom/ScriptSettings.h"
11 : #include "mozilla/MemoryReporting.h"
12 : #include "mozilla/ModuleLoader.h"
13 : #include "nsAutoPtr.h"
14 : #include "nsISupports.h"
15 : #include "nsIObserver.h"
16 : #include "nsIURI.h"
17 : #include "xpcIJSModuleLoader.h"
18 : #include "nsClassHashtable.h"
19 : #include "nsDataHashtable.h"
20 : #include "jsapi.h"
21 :
22 : #include "xpcIJSGetFactory.h"
23 :
24 : class nsIFile;
25 : class nsIPrincipal;
26 : class nsIXPConnectJSObjectHolder;
27 : class ComponentLoaderInfo;
28 :
29 : /* 6bd13476-1dd2-11b2-bbef-f0ccb5fa64b6 (thanks, mozbot) */
30 :
31 : #define MOZJSCOMPONENTLOADER_CID \
32 : {0x6bd13476, 0x1dd2, 0x11b2, \
33 : { 0xbb, 0xef, 0xf0, 0xcc, 0xb5, 0xfa, 0x64, 0xb6 }}
34 : #define MOZJSCOMPONENTLOADER_CONTRACTID "@mozilla.org/moz/jsloader;1"
35 :
36 : class mozJSComponentLoader : public mozilla::ModuleLoader,
37 : public xpcIJSModuleLoader,
38 : public nsIObserver
39 : {
40 : public:
41 : NS_DECL_ISUPPORTS
42 : NS_DECL_XPCIJSMODULELOADER
43 : NS_DECL_NSIOBSERVER
44 :
45 : mozJSComponentLoader();
46 :
47 : // ModuleLoader
48 : const mozilla::Module* LoadModule(mozilla::FileLocation& aFile) override;
49 :
50 : void FindTargetObject(JSContext* aCx,
51 : JS::MutableHandleObject aTargetObject);
52 :
53 2 : static mozJSComponentLoader* Get() { return sSelf; }
54 :
55 : size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
56 :
57 : protected:
58 : virtual ~mozJSComponentLoader();
59 :
60 : static mozJSComponentLoader* sSelf;
61 :
62 : nsresult ReallyInit();
63 : void UnloadModules();
64 :
65 : void CreateLoaderGlobal(JSContext* aCx,
66 : nsACString& aLocation,
67 : JSAddonId* aAddonID,
68 : JS::MutableHandleObject aGlobal);
69 :
70 : JSObject* PrepareObjectForLocation(JSContext* aCx,
71 : nsIFile* aComponentFile,
72 : nsIURI* aComponent,
73 : bool* aRealFile);
74 :
75 : nsresult ObjectForLocation(ComponentLoaderInfo& aInfo,
76 : nsIFile* aComponentFile,
77 : JS::MutableHandleObject aObject,
78 : JS::MutableHandleScript aTableScript,
79 : char** location,
80 : bool aCatchException,
81 : JS::MutableHandleValue aException);
82 :
83 : nsresult ImportInto(const nsACString& aLocation,
84 : JS::HandleObject targetObj,
85 : JSContext* callercx,
86 : JS::MutableHandleObject vp);
87 :
88 : nsCOMPtr<nsIComponentManager> mCompMgr;
89 :
90 : class ModuleEntry : public mozilla::Module
91 : {
92 : public:
93 255 : explicit ModuleEntry(JS::RootingContext* aRootingCx)
94 255 : : mozilla::Module(), obj(aRootingCx), thisObjectKey(aRootingCx)
95 : {
96 255 : mVersion = mozilla::Module::kVersion;
97 255 : mCIDs = nullptr;
98 255 : mContractIDs = nullptr;
99 255 : mCategoryEntries = nullptr;
100 255 : getFactoryProc = GetFactory;
101 255 : loadProc = nullptr;
102 255 : unloadProc = nullptr;
103 :
104 255 : location = nullptr;
105 255 : }
106 :
107 0 : ~ModuleEntry() {
108 0 : Clear();
109 0 : }
110 :
111 0 : void Clear() {
112 0 : getfactoryobj = nullptr;
113 :
114 0 : if (obj) {
115 0 : mozilla::AutoJSContext cx;
116 0 : JSAutoCompartment ac(cx, obj);
117 :
118 0 : if (JS_HasExtensibleLexicalEnvironment(obj)) {
119 0 : JS_SetAllNonReservedSlotsToUndefined(cx, JS_ExtensibleLexicalEnvironment(obj));
120 : }
121 0 : JS_SetAllNonReservedSlotsToUndefined(cx, obj);
122 0 : obj = nullptr;
123 0 : thisObjectKey = nullptr;
124 : }
125 :
126 0 : if (location)
127 0 : free(location);
128 :
129 0 : obj = nullptr;
130 0 : thisObjectKey = nullptr;
131 0 : location = nullptr;
132 0 : }
133 :
134 : size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
135 :
136 : static already_AddRefed<nsIFactory> GetFactory(const mozilla::Module& module,
137 : const mozilla::Module::CIDEntry& entry);
138 :
139 : nsCOMPtr<xpcIJSGetFactory> getfactoryobj;
140 : JS::PersistentRootedObject obj;
141 : JS::PersistentRootedScript thisObjectKey;
142 : char* location;
143 : };
144 :
145 : friend class ModuleEntry;
146 :
147 : static size_t DataEntrySizeOfExcludingThis(const nsACString& aKey, ModuleEntry* const& aData,
148 : mozilla::MallocSizeOf aMallocSizeOf, void* arg);
149 : static size_t ClassEntrySizeOfExcludingThis(const nsACString& aKey,
150 : const nsAutoPtr<ModuleEntry>& aData,
151 : mozilla::MallocSizeOf aMallocSizeOf, void* arg);
152 :
153 : // Modules are intentionally leaked, but still cleared.
154 : nsDataHashtable<nsCStringHashKey, ModuleEntry*> mModules;
155 :
156 : nsClassHashtable<nsCStringHashKey, ModuleEntry> mImports;
157 : nsDataHashtable<nsCStringHashKey, ModuleEntry*> mInProgressImports;
158 :
159 : bool mInitialized;
160 : };
161 :
162 : #endif
|