Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 mozilla_dom_ScriptLoadRequest_h
8 : #define mozilla_dom_ScriptLoadRequest_h
9 :
10 : #include "mozilla/CORSMode.h"
11 : #include "mozilla/dom/SRIMetadata.h"
12 : #include "mozilla/LinkedList.h"
13 : #include "mozilla/net/ReferrerPolicy.h"
14 : #include "mozilla/Vector.h"
15 : #include "nsCOMPtr.h"
16 : #include "nsCycleCollectionParticipant.h"
17 : #include "nsIScriptElement.h"
18 :
19 : class nsICacheInfoChannel;
20 :
21 : namespace mozilla {
22 : namespace dom {
23 :
24 : class ModuleLoadRequest;
25 : class ScriptLoadRequestList;
26 :
27 : enum class ScriptKind {
28 : Classic,
29 : Module
30 : };
31 :
32 : /*
33 : * A class that handles loading and evaluation of <script> elements.
34 : */
35 :
36 : class ScriptLoadRequest : public nsISupports,
37 : private mozilla::LinkedListElement<ScriptLoadRequest>
38 : {
39 : typedef LinkedListElement<ScriptLoadRequest> super;
40 :
41 : // Allow LinkedListElement<ScriptLoadRequest> to cast us to itself as needed.
42 : friend class mozilla::LinkedListElement<ScriptLoadRequest>;
43 : friend class ScriptLoadRequestList;
44 :
45 : protected:
46 : virtual ~ScriptLoadRequest();
47 :
48 : public:
49 : ScriptLoadRequest(ScriptKind aKind,
50 : nsIScriptElement* aElement,
51 : uint32_t aVersion,
52 : mozilla::CORSMode aCORSMode,
53 : const mozilla::dom::SRIMetadata &aIntegrity);
54 :
55 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
56 45 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ScriptLoadRequest)
57 :
58 49 : bool IsModuleRequest() const
59 : {
60 49 : return mKind == ScriptKind::Module;
61 : }
62 :
63 : ModuleLoadRequest* AsModuleRequest();
64 :
65 5 : void FireScriptAvailable(nsresult aResult)
66 : {
67 5 : mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
68 5 : }
69 5 : void FireScriptEvaluated(nsresult aResult)
70 : {
71 5 : mElement->ScriptEvaluated(aResult, mElement, mIsInline);
72 5 : }
73 :
74 6 : bool IsPreload()
75 : {
76 6 : return mElement == nullptr;
77 : }
78 :
79 : virtual void Cancel();
80 :
81 12 : bool IsCanceled() const
82 : {
83 12 : return mIsCanceled;
84 : }
85 :
86 : virtual void SetReady();
87 :
88 : void** OffThreadTokenPtr()
89 : {
90 : return mOffThreadToken ? &mOffThreadToken : nullptr;
91 : }
92 :
93 8 : bool IsTracking() const
94 : {
95 8 : return mIsTracking;
96 : }
97 0 : void SetIsTracking()
98 : {
99 0 : MOZ_ASSERT(!mIsTracking);
100 0 : mIsTracking = true;
101 0 : }
102 :
103 : enum class Progress : uint8_t {
104 : Loading, // Request either source or bytecode
105 : Loading_Source, // Explicitly Request source stream
106 : Compiling,
107 : FetchingImports,
108 : Ready
109 : };
110 :
111 28 : bool IsReadyToRun() const {
112 28 : return mProgress == Progress::Ready;
113 : }
114 20 : bool IsLoading() const {
115 20 : return mProgress == Progress::Loading ||
116 20 : mProgress == Progress::Loading_Source;
117 : }
118 4 : bool IsLoadingSource() const {
119 4 : return mProgress == Progress::Loading_Source;
120 : }
121 4 : bool InCompilingStage() const {
122 8 : return mProgress == Progress::Compiling ||
123 9 : (IsReadyToRun() && mWasCompiledOMT);
124 : }
125 :
126 : // Type of data provided by the nsChannel.
127 : enum class DataType : uint8_t {
128 : Unknown,
129 : Source,
130 : Bytecode
131 : };
132 :
133 20 : bool IsUnknownDataType() const {
134 20 : return mDataType == DataType::Unknown;
135 : }
136 24 : bool IsSource() const {
137 24 : return mDataType == DataType::Source;
138 : }
139 5 : bool IsBytecode() const {
140 5 : return mDataType == DataType::Bytecode;
141 : }
142 :
143 : void MaybeCancelOffThreadScript();
144 : void DropBytecodeCacheReferences();
145 :
146 : using super::getNext;
147 : using super::isInList;
148 :
149 : const ScriptKind mKind;
150 : nsCOMPtr<nsIScriptElement> mElement;
151 : bool mScriptFromHead; // Synchronous head script block loading of other non js/css content.
152 : Progress mProgress; // Are we still waiting for a load to complete?
153 : DataType mDataType; // Does this contain Source or Bytecode?
154 : bool mIsInline; // Is the script inline or loaded?
155 : bool mHasSourceMapURL; // Does the HTTP header have a source map url?
156 : bool mIsDefer; // True if we live in mDeferRequests.
157 : bool mIsAsync; // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
158 : bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
159 : bool mIsXSLT; // True if we live in mXSLTRequests.
160 : bool mIsCanceled; // True if we have been explicitly canceled.
161 : bool mWasCompiledOMT; // True if the script has been compiled off main thread.
162 : bool mIsTracking; // True if the script comes from a source on our tracking protection list.
163 : void* mOffThreadToken; // Off-thread parsing token.
164 : nsString mSourceMapURL; // Holds source map url for loaded scripts
165 :
166 : // Holds the top-level JSScript that corresponds to the current source, once
167 : // it is parsed, and planned to be saved in the bytecode cache.
168 : JS::Heap<JSScript*> mScript;
169 :
170 : // Holds script text for non-inline scripts. Don't use nsString so we can give
171 : // ownership to jsapi.
172 : mozilla::Vector<char16_t> mScriptText;
173 :
174 : // Holds the SRI serialized hash and the script bytecode for non-inline
175 : // scripts.
176 : mozilla::Vector<uint8_t> mScriptBytecode;
177 : uint32_t mBytecodeOffset; // Offset of the bytecode in mScriptBytecode
178 :
179 : uint32_t mJSVersion;
180 : nsCOMPtr<nsIURI> mURI;
181 : nsCOMPtr<nsIPrincipal> mOriginPrincipal;
182 : nsAutoCString mURL; // Keep the URI's filename alive during off thread parsing.
183 : int32_t mLineNo;
184 : const mozilla::CORSMode mCORSMode;
185 : const mozilla::dom::SRIMetadata mIntegrity;
186 : mozilla::net::ReferrerPolicy mReferrerPolicy;
187 :
188 : // Holds the Cache information, which is used to register the bytecode
189 : // on the cache entry, such that we can load it the next time.
190 : nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
191 : };
192 :
193 330 : class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest>
194 : {
195 : typedef mozilla::LinkedList<ScriptLoadRequest> super;
196 :
197 : public:
198 : ~ScriptLoadRequestList();
199 :
200 : void Clear();
201 :
202 : #ifdef DEBUG
203 : bool Contains(ScriptLoadRequest* aElem) const;
204 : #endif // DEBUG
205 :
206 : using super::getFirst;
207 : using super::isEmpty;
208 :
209 0 : void AppendElement(ScriptLoadRequest* aElem)
210 : {
211 0 : MOZ_ASSERT(!aElem->isInList());
212 0 : NS_ADDREF(aElem);
213 0 : insertBack(aElem);
214 0 : }
215 :
216 : MOZ_MUST_USE
217 0 : already_AddRefed<ScriptLoadRequest> Steal(ScriptLoadRequest* aElem)
218 : {
219 0 : aElem->removeFrom(*this);
220 0 : return dont_AddRef(aElem);
221 : }
222 :
223 : MOZ_MUST_USE
224 0 : already_AddRefed<ScriptLoadRequest> StealFirst()
225 : {
226 0 : MOZ_ASSERT(!isEmpty());
227 0 : return Steal(getFirst());
228 : }
229 :
230 : void Remove(ScriptLoadRequest* aElem)
231 : {
232 : aElem->removeFrom(*this);
233 : NS_RELEASE(aElem);
234 : }
235 : };
236 :
237 : void
238 : ImplCycleCollectionUnlink(ScriptLoadRequestList& aField);
239 :
240 : void
241 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
242 : ScriptLoadRequestList& aField,
243 : const char* aName,
244 : uint32_t aFlags);
245 :
246 : } // namespace dom
247 : } // namespace mozilla
248 :
249 : #endif // mozilla_dom_ScriptLoadRequest_h
|