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 : #include "ModuleLoadRequest.h"
8 : #include "mozilla/HoldDropJSObjects.h"
9 : #include "nsICacheInfoChannel.h"
10 : #include "ScriptLoadRequest.h"
11 : #include "ScriptSettings.h"
12 :
13 : namespace mozilla {
14 : namespace dom {
15 :
16 : //////////////////////////////////////////////////////////////
17 : // ScriptLoadRequest
18 : //////////////////////////////////////////////////////////////
19 :
20 5 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptLoadRequest)
21 0 : NS_INTERFACE_MAP_END
22 :
23 20 : NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoadRequest)
24 20 : NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadRequest)
25 :
26 : NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
27 :
28 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
29 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheInfo)
30 0 : tmp->DropBytecodeCacheReferences();
31 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
32 :
33 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest)
34 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheInfo)
35 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
36 :
37 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadRequest)
38 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScript)
39 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
40 :
41 5 : ScriptLoadRequest::ScriptLoadRequest(ScriptKind aKind,
42 : nsIScriptElement* aElement,
43 : uint32_t aVersion,
44 : mozilla::CORSMode aCORSMode,
45 5 : const mozilla::dom::SRIMetadata& aIntegrity)
46 : : mKind(aKind)
47 : , mElement(aElement)
48 : , mScriptFromHead(false)
49 : , mProgress(Progress::Loading)
50 : , mDataType(DataType::Unknown)
51 : , mIsInline(true)
52 : , mHasSourceMapURL(false)
53 : , mIsDefer(false)
54 : , mIsAsync(false)
55 : , mIsNonAsyncScriptInserted(false)
56 : , mIsXSLT(false)
57 : , mIsCanceled(false)
58 : , mWasCompiledOMT(false)
59 : , mIsTracking(false)
60 : , mOffThreadToken(nullptr)
61 : , mScriptText()
62 : , mScriptBytecode()
63 : , mBytecodeOffset(0)
64 : , mJSVersion(aVersion)
65 : , mLineNo(1)
66 : , mCORSMode(aCORSMode)
67 : , mIntegrity(aIntegrity)
68 5 : , mReferrerPolicy(mozilla::net::RP_Unset)
69 : {
70 5 : }
71 :
72 0 : ScriptLoadRequest::~ScriptLoadRequest()
73 : {
74 : // We should always clean up any off-thread script parsing resources.
75 0 : MOZ_ASSERT(!mOffThreadToken);
76 :
77 : // But play it safe in release builds and try to clean them up here
78 : // as a fail safe.
79 0 : MaybeCancelOffThreadScript();
80 :
81 0 : if (mScript) {
82 0 : DropBytecodeCacheReferences();
83 : }
84 0 : }
85 :
86 : void
87 4 : ScriptLoadRequest::SetReady()
88 : {
89 4 : MOZ_ASSERT(mProgress != Progress::Ready);
90 4 : mProgress = Progress::Ready;
91 4 : }
92 :
93 : void
94 0 : ScriptLoadRequest::Cancel()
95 : {
96 0 : MaybeCancelOffThreadScript();
97 0 : mIsCanceled = true;
98 0 : }
99 :
100 : void
101 0 : ScriptLoadRequest::MaybeCancelOffThreadScript()
102 : {
103 0 : MOZ_ASSERT(NS_IsMainThread());
104 :
105 0 : if (!mOffThreadToken) {
106 0 : return;
107 : }
108 :
109 0 : JSContext* cx = danger::GetJSContext();
110 : // Follow the same conditions as ScriptLoader::AttemptAsyncScriptCompile
111 0 : if (IsModuleRequest()) {
112 0 : JS::CancelOffThreadModule(cx, mOffThreadToken);
113 0 : } else if (IsSource()) {
114 0 : JS::CancelOffThreadScript(cx, mOffThreadToken);
115 : } else {
116 0 : MOZ_ASSERT(IsBytecode());
117 0 : JS::CancelOffThreadScriptDecoder(cx, mOffThreadToken);
118 : }
119 0 : mOffThreadToken = nullptr;
120 : }
121 :
122 : void
123 0 : ScriptLoadRequest::DropBytecodeCacheReferences()
124 : {
125 0 : mCacheInfo = nullptr;
126 0 : mScript = nullptr;
127 0 : DropJSObjects(this);
128 0 : }
129 :
130 : inline ModuleLoadRequest*
131 0 : ScriptLoadRequest::AsModuleRequest()
132 : {
133 0 : MOZ_ASSERT(IsModuleRequest());
134 0 : return static_cast<ModuleLoadRequest*>(this);
135 : }
136 :
137 : //////////////////////////////////////////////////////////////
138 : // ScriptLoadRequestList
139 : //////////////////////////////////////////////////////////////
140 :
141 0 : ScriptLoadRequestList::~ScriptLoadRequestList()
142 : {
143 0 : Clear();
144 0 : }
145 :
146 : void
147 0 : ScriptLoadRequestList::Clear()
148 : {
149 0 : while (!isEmpty()) {
150 0 : RefPtr<ScriptLoadRequest> first = StealFirst();
151 0 : first->Cancel();
152 : // And just let it go out of scope and die.
153 : }
154 0 : }
155 :
156 : #ifdef DEBUG
157 : bool
158 16 : ScriptLoadRequestList::Contains(ScriptLoadRequest* aElem) const
159 : {
160 16 : for (const ScriptLoadRequest* req = getFirst();
161 16 : req; req = req->getNext()) {
162 0 : if (req == aElem) {
163 0 : return true;
164 : }
165 : }
166 :
167 16 : return false;
168 : }
169 : #endif // DEBUG
170 :
171 : inline void
172 0 : ImplCycleCollectionUnlink(ScriptLoadRequestList& aField)
173 : {
174 0 : while (!aField.isEmpty()) {
175 0 : RefPtr<ScriptLoadRequest> first = aField.StealFirst();
176 : }
177 0 : }
178 :
179 : inline void
180 0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
181 : ScriptLoadRequestList& aField,
182 : const char* aName,
183 : uint32_t aFlags)
184 : {
185 0 : for (ScriptLoadRequest* request = aField.getFirst();
186 0 : request; request = request->getNext())
187 : {
188 0 : CycleCollectionNoteChild(aCallback, request, aName, aFlags);
189 : }
190 0 : }
191 :
192 : } // dom namespace
193 : } // mozilla namespace
|