| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/dom/ClassicPendingScript.h" | 5 #include "core/dom/ClassicPendingScript.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ScriptSourceCode.h" | 7 #include "bindings/core/v8/ScriptSourceCode.h" |
| 8 #include "bindings/core/v8/ScriptState.h" | 8 #include "bindings/core/v8/ScriptState.h" |
| 9 #include "bindings/core/v8/ScriptStreamer.h" | 9 #include "bindings/core/v8/ScriptStreamer.h" |
| 10 #include "bindings/core/v8/V8BindingForCore.h" | 10 #include "bindings/core/v8/V8BindingForCore.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 ClassicPendingScript* ClassicPendingScript::Create( | 24 ClassicPendingScript* ClassicPendingScript::Create( |
| 25 ScriptElementBase* element, | 25 ScriptElementBase* element, |
| 26 const TextPosition& starting_position) { | 26 const TextPosition& starting_position) { |
| 27 return new ClassicPendingScript(element, nullptr, starting_position); | 27 return new ClassicPendingScript(element, nullptr, starting_position); |
| 28 } | 28 } |
| 29 | 29 |
| 30 ClassicPendingScript::ClassicPendingScript( | 30 ClassicPendingScript::ClassicPendingScript( |
| 31 ScriptElementBase* element, | 31 ScriptElementBase* element, |
| 32 ScriptResource* resource, | 32 ScriptResource* resource, |
| 33 const TextPosition& starting_position) | 33 const TextPosition& starting_position) |
| 34 : PendingScript(element, starting_position), integrity_failure_(false) { | 34 : PendingScript(element, starting_position), |
| 35 ready_state_(resource ? kWaitingForResource : kReady), |
| 36 integrity_failure_(false) { |
| 35 CheckState(); | 37 CheckState(); |
| 36 SetResource(resource); | 38 SetResource(resource); |
| 37 MemoryCoordinator::Instance().RegisterClient(this); | 39 MemoryCoordinator::Instance().RegisterClient(this); |
| 38 } | 40 } |
| 39 | 41 |
| 40 ClassicPendingScript::~ClassicPendingScript() {} | 42 ClassicPendingScript::~ClassicPendingScript() {} |
| 41 | 43 |
| 42 NOINLINE void ClassicPendingScript::CheckState() const { | 44 NOINLINE void ClassicPendingScript::CheckState() const { |
| 43 // TODO(hiroshige): Turn these CHECK()s into DCHECK() before going to beta. | 45 // TODO(hiroshige): Turn these CHECK()s into DCHECK() before going to beta. |
| 44 CHECK(!prefinalizer_called_); | 46 CHECK(!prefinalizer_called_); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 60 SetResource(nullptr); | 62 SetResource(nullptr); |
| 61 integrity_failure_ = false; | 63 integrity_failure_ = false; |
| 62 if (streamer_) | 64 if (streamer_) |
| 63 streamer_->Cancel(); | 65 streamer_->Cancel(); |
| 64 streamer_ = nullptr; | 66 streamer_ = nullptr; |
| 65 } | 67 } |
| 66 | 68 |
| 67 void ClassicPendingScript::StreamingFinished() { | 69 void ClassicPendingScript::StreamingFinished() { |
| 68 CheckState(); | 70 CheckState(); |
| 69 DCHECK(GetResource()); | 71 DCHECK(GetResource()); |
| 70 if (Client()) | 72 DCHECK_EQ(ready_state_, kWaitingForStreaming); |
| 71 Client()->PendingScriptFinished(this); | 73 |
| 74 bool error_occurred = GetResource()->ErrorOccurred() || integrity_failure_; |
| 75 AdvanceReadyState(error_occurred ? kErrorOccurred : kReady); |
| 72 } | 76 } |
| 73 | 77 |
| 74 // Returns true if SRI check passed. | 78 // Returns true if SRI check passed. |
| 75 static bool CheckScriptResourceIntegrity(Resource* resource, | 79 static bool CheckScriptResourceIntegrity(Resource* resource, |
| 76 ScriptElementBase* element) { | 80 ScriptElementBase* element) { |
| 77 DCHECK_EQ(resource->GetType(), Resource::kScript); | 81 DCHECK_EQ(resource->GetType(), Resource::kScript); |
| 78 ScriptResource* script_resource = ToScriptResource(resource); | 82 ScriptResource* script_resource = ToScriptResource(resource); |
| 79 String integrity_attr = element->IntegrityAttributeValue(); | 83 String integrity_attr = element->IntegrityAttributeValue(); |
| 80 | 84 |
| 81 // It is possible to get back a script resource with integrity metadata | 85 // It is possible to get back a script resource with integrity metadata |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 // fetch JavaScript API. In a future world where the ResourceFetcher uses | 141 // fetch JavaScript API. In a future world where the ResourceFetcher uses |
| 138 // the Fetch algorithm, this should be fixed by having separate Response | 142 // the Fetch algorithm, this should be fixed by having separate Response |
| 139 // objects (perhaps attached to identical Resource objects) per request. | 143 // objects (perhaps attached to identical Resource objects) per request. |
| 140 // | 144 // |
| 141 // See https://crbug.com/500701 for more information. | 145 // See https://crbug.com/500701 for more information. |
| 142 CheckState(); | 146 CheckState(); |
| 143 if (GetElement()) { | 147 if (GetElement()) { |
| 144 integrity_failure_ = !CheckScriptResourceIntegrity(resource, GetElement()); | 148 integrity_failure_ = !CheckScriptResourceIntegrity(resource, GetElement()); |
| 145 } | 149 } |
| 146 | 150 |
| 147 // If script streaming is in use, the client will be notified in | 151 // We are now waiting for script streaming to finish. |
| 148 // streamingFinished. | 152 // If there is no script streamer, this step completes immediately. |
| 153 AdvanceReadyState(kWaitingForStreaming); |
| 149 if (streamer_) | 154 if (streamer_) |
| 150 streamer_->NotifyFinished(resource); | 155 streamer_->NotifyFinished(resource); |
| 151 else if (Client()) | 156 else |
| 152 Client()->PendingScriptFinished(this); | 157 StreamingFinished(); |
| 153 } | 158 } |
| 154 | 159 |
| 155 void ClassicPendingScript::NotifyAppendData(ScriptResource* resource) { | 160 void ClassicPendingScript::NotifyAppendData(ScriptResource* resource) { |
| 156 if (streamer_) | 161 if (streamer_) |
| 157 streamer_->NotifyAppendData(resource); | 162 streamer_->NotifyAppendData(resource); |
| 158 } | 163 } |
| 159 | 164 |
| 160 DEFINE_TRACE(ClassicPendingScript) { | 165 DEFINE_TRACE(ClassicPendingScript) { |
| 161 visitor->Trace(streamer_); | 166 visitor->Trace(streamer_); |
| 162 ResourceOwner<ScriptResource>::Trace(visitor); | 167 ResourceOwner<ScriptResource>::Trace(visitor); |
| 163 MemoryCoordinatorClient::Trace(visitor); | 168 MemoryCoordinatorClient::Trace(visitor); |
| 164 PendingScript::Trace(visitor); | 169 PendingScript::Trace(visitor); |
| 165 } | 170 } |
| 166 | 171 |
| 167 ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url, | 172 ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url, |
| 168 bool& error_occurred) const { | 173 bool& error_occurred) const { |
| 169 CheckState(); | 174 CheckState(); |
| 175 DCHECK(IsReady()); |
| 170 | 176 |
| 171 error_occurred = this->ErrorOccurred(); | 177 error_occurred = ErrorOccurred(); |
| 172 if (GetResource()) { | 178 if (GetResource()) { |
| 173 DCHECK(GetResource()->IsLoaded()); | 179 DCHECK(GetResource()->IsLoaded()); |
| 174 if (streamer_ && !streamer_->StreamingSuppressed()) | 180 if (streamer_ && !streamer_->StreamingSuppressed()) |
| 175 return ClassicScript::Create(ScriptSourceCode(streamer_, GetResource())); | 181 return ClassicScript::Create(ScriptSourceCode(streamer_, GetResource())); |
| 176 return ClassicScript::Create(ScriptSourceCode(GetResource())); | 182 return ClassicScript::Create(ScriptSourceCode(GetResource())); |
| 177 } | 183 } |
| 178 | 184 |
| 179 return ClassicScript::Create(ScriptSourceCode( | 185 return ClassicScript::Create(ScriptSourceCode( |
| 180 GetElement()->TextContent(), document_url, StartingPosition())); | 186 GetElement()->TextContent(), document_url, StartingPosition())); |
| 181 } | 187 } |
| 182 | 188 |
| 183 void ClassicPendingScript::SetStreamer(ScriptStreamer* streamer) { | 189 void ClassicPendingScript::SetStreamer(ScriptStreamer* streamer) { |
| 184 DCHECK(!streamer_); | 190 DCHECK(!streamer_); |
| 185 DCHECK(!IsWatchingForLoad()); | 191 DCHECK(!IsWatchingForLoad()); |
| 192 DCHECK(!streamer->IsFinished()); |
| 193 DCHECK_LT(ready_state_, kWaitingForStreaming); |
| 186 streamer_ = streamer; | 194 streamer_ = streamer; |
| 187 CheckState(); | 195 CheckState(); |
| 188 } | 196 } |
| 189 | 197 |
| 190 bool ClassicPendingScript::IsReady() const { | 198 bool ClassicPendingScript::IsReady() const { |
| 191 CheckState(); | 199 CheckState(); |
| 192 if (GetResource()) { | 200 return ready_state_ >= kReady; |
| 193 return GetResource()->IsLoaded() && (!streamer_ || streamer_->IsFinished()); | |
| 194 } | |
| 195 | |
| 196 return true; | |
| 197 } | 201 } |
| 198 | 202 |
| 199 bool ClassicPendingScript::ErrorOccurred() const { | 203 bool ClassicPendingScript::ErrorOccurred() const { |
| 200 CheckState(); | 204 CheckState(); |
| 201 if (GetResource()) | 205 return ready_state_ == kErrorOccurred; |
| 202 return GetResource()->ErrorOccurred() || integrity_failure_; | 206 } |
| 203 | 207 |
| 204 return false; | 208 void ClassicPendingScript::AdvanceReadyState(ReadyState new_ready_state) { |
| 209 CHECK_GT(new_ready_state, ready_state_) |
| 210 << "The ready state should monotonically advance."; |
| 211 |
| 212 if (new_ready_state >= kReady) { |
| 213 CHECK_LT(ready_state_, kReady) |
| 214 << "The state should not advance from one completed state to another."; |
| 215 } |
| 216 |
| 217 ready_state_ = new_ready_state; |
| 218 |
| 219 if (ready_state_ >= kReady && IsWatchingForLoad()) |
| 220 Client()->PendingScriptFinished(this); |
| 205 } | 221 } |
| 206 | 222 |
| 207 void ClassicPendingScript::OnPurgeMemory() { | 223 void ClassicPendingScript::OnPurgeMemory() { |
| 208 CheckState(); | 224 CheckState(); |
| 209 if (!streamer_) | 225 if (!streamer_) |
| 210 return; | 226 return; |
| 211 streamer_->Cancel(); | 227 streamer_->Cancel(); |
| 212 streamer_ = nullptr; | 228 streamer_ = nullptr; |
| 213 } | 229 } |
| 214 | 230 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 233 | 249 |
| 234 KURL ClassicPendingScript::UrlForClassicScript() const { | 250 KURL ClassicPendingScript::UrlForClassicScript() const { |
| 235 return GetResource()->Url(); | 251 return GetResource()->Url(); |
| 236 } | 252 } |
| 237 | 253 |
| 238 void ClassicPendingScript::RemoveFromMemoryCache() { | 254 void ClassicPendingScript::RemoveFromMemoryCache() { |
| 239 GetMemoryCache()->Remove(GetResource()); | 255 GetMemoryCache()->Remove(GetResource()); |
| 240 } | 256 } |
| 241 | 257 |
| 242 } // namespace blink | 258 } // namespace blink |
| OLD | NEW |