Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp

Issue 2723793002: De-Element ScriptLoader (Closed)
Patch Set: De-Element ScriptLoader Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #include "public/platform/Platform.h" 48 #include "public/platform/Platform.h"
49 #include <inttypes.h> 49 #include <inttypes.h>
50 #include <memory> 50 #include <memory>
51 51
52 namespace blink { 52 namespace blink {
53 53
54 namespace { 54 namespace {
55 55
56 // TODO(bmcquade): move this to a shared location if we find ourselves wanting 56 // TODO(bmcquade): move this to a shared location if we find ourselves wanting
57 // to trace similar data elsewhere in the codebase. 57 // to trace similar data elsewhere in the codebase.
58 std::unique_ptr<TracedValue> getTraceArgsForScriptElement( 58 std::unique_ptr<TracedValue> getTraceArgsForScriptLoaderClient(
59 Element* element, 59 ScriptLoaderClient* client,
60 const TextPosition& textPosition) { 60 const TextPosition& textPosition) {
61 std::unique_ptr<TracedValue> value = TracedValue::create(); 61 std::unique_ptr<TracedValue> value = TracedValue::create();
62 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element); 62 ScriptLoader* scriptLoader = client->loader();
63 if (scriptLoader && scriptLoader->resource()) 63 if (scriptLoader && scriptLoader->resource())
64 value->setString("url", scriptLoader->resource()->url().getString()); 64 value->setString("url", scriptLoader->resource()->url().getString());
65 if (element->ownerDocument() && element->ownerDocument()->frame()) { 65 if (client->document().frame()) {
hiroshige 2017/03/01 00:58:15 This changes the behavior: ownerDocument() -> docu
Nate Chapin 2017/03/01 21:34:59 Node::document() and Node::ownerDocument() are equ
hiroshige 2017/03/06 22:54:03 Acknowledged.
66 value->setString( 66 value->setString(
67 "frame", 67 "frame",
68 String::format("0x%" PRIx64, 68 String::format("0x%" PRIx64,
69 static_cast<uint64_t>(reinterpret_cast<intptr_t>( 69 static_cast<uint64_t>(reinterpret_cast<intptr_t>(
70 element->ownerDocument()->frame())))); 70 client->document().frame()))));
71 } 71 }
72 if (textPosition.m_line.zeroBasedInt() > 0 || 72 if (textPosition.m_line.zeroBasedInt() > 0 ||
73 textPosition.m_column.zeroBasedInt() > 0) { 73 textPosition.m_column.zeroBasedInt() > 0) {
74 value->setInteger("lineNumber", textPosition.m_line.oneBasedInt()); 74 value->setInteger("lineNumber", textPosition.m_line.oneBasedInt());
75 value->setInteger("columnNumber", textPosition.m_column.oneBasedInt()); 75 value->setInteger("columnNumber", textPosition.m_column.oneBasedInt());
76 } 76 }
77 return value; 77 return value;
78 } 78 }
79 79
80 bool doExecuteScript(Element* scriptElement, 80 bool doExecuteScript(ScriptLoaderClient* client,
81 const ScriptSourceCode& sourceCode, 81 const ScriptSourceCode& sourceCode,
82 const TextPosition& textPosition) { 82 const TextPosition& textPosition) {
83 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(scriptElement); 83 ScriptLoader* scriptLoader = client->loader();
84 DCHECK(scriptLoader); 84 DCHECK(scriptLoader);
85 TRACE_EVENT_WITH_FLOW1( 85 TRACE_EVENT_WITH_FLOW1(
86 "blink", "HTMLParserScriptRunner ExecuteScript", scriptElement, 86 "blink", "HTMLParserScriptRunner ExecuteScript", client,
Nate Chapin 2017/02/28 21:39:29 Here and below: these TRACE_EVENT changes are prob
87 TRACE_EVENT_FLAG_FLOW_IN, "data", 87 TRACE_EVENT_FLAG_FLOW_IN, "data",
88 getTraceArgsForScriptElement(scriptElement, textPosition)); 88 getTraceArgsForScriptLoaderClient(client, textPosition));
89 return scriptLoader->executeScript(sourceCode); 89 return scriptLoader->executeScript(sourceCode);
90 } 90 }
91 91
92 void traceParserBlockingScript(const PendingScript* pendingScript, 92 void traceParserBlockingScript(const PendingScript* pendingScript,
93 bool waitingForResources) { 93 bool waitingForResources) {
94 // The HTML parser must yield before executing script in the following 94 // The HTML parser must yield before executing script in the following
95 // cases: 95 // cases:
96 // * the script's execution is blocked on the completed load of the script 96 // * the script's execution is blocked on the completed load of the script
97 // resource 97 // resource
98 // (https://html.spec.whatwg.org/multipage/scripting.html#pending-parsing-bl ocking-script) 98 // (https://html.spec.whatwg.org/multipage/scripting.html#pending-parsing-bl ocking-script)
99 // * the script's execution is blocked on the load of a style sheet or other 99 // * the script's execution is blocked on the load of a style sheet or other
100 // resources that are blocking scripts 100 // resources that are blocking scripts
101 // (https://html.spec.whatwg.org/multipage/semantics.html#a-style-sheet-that -is-blocking-scripts) 101 // (https://html.spec.whatwg.org/multipage/semantics.html#a-style-sheet-that -is-blocking-scripts)
102 // 102 //
103 // Both of these cases can introduce significant latency when loading a 103 // Both of these cases can introduce significant latency when loading a
104 // web page, especially for users on slow connections, since the HTML parser 104 // web page, especially for users on slow connections, since the HTML parser
105 // must yield until the blocking resources finish loading. 105 // must yield until the blocking resources finish loading.
106 // 106 //
107 // We trace these parser yields here using flow events, so we can track 107 // We trace these parser yields here using flow events, so we can track
108 // both when these yields occur, as well as how long the parser had 108 // both when these yields occur, as well as how long the parser had
109 // to yield. The connecting flow events are traced once the parser becomes 109 // to yield. The connecting flow events are traced once the parser becomes
110 // unblocked when the script actually executes, in doExecuteScript. 110 // unblocked when the script actually executes, in doExecuteScript.
111 Element* element = pendingScript->element(); 111 ScriptLoaderClient* client = pendingScript->scriptLoaderClient();
112 if (!element) 112 if (!client)
113 return; 113 return;
114 TextPosition scriptStartPosition = pendingScript->startingPosition(); 114 TextPosition scriptStartPosition = pendingScript->startingPosition();
115 if (!pendingScript->isReady()) { 115 if (!pendingScript->isReady()) {
116 if (waitingForResources) { 116 if (waitingForResources) {
117 TRACE_EVENT_WITH_FLOW1( 117 TRACE_EVENT_WITH_FLOW1(
118 "blink", "YieldParserForScriptLoadAndBlockingResources", element, 118 "blink", "YieldParserForScriptLoadAndBlockingResources", client,
119 TRACE_EVENT_FLAG_FLOW_OUT, "data", 119 TRACE_EVENT_FLAG_FLOW_OUT, "data",
120 getTraceArgsForScriptElement(element, scriptStartPosition)); 120 getTraceArgsForScriptLoaderClient(client, scriptStartPosition));
121 } else { 121 } else {
122 TRACE_EVENT_WITH_FLOW1( 122 TRACE_EVENT_WITH_FLOW1(
123 "blink", "YieldParserForScriptLoad", element, 123 "blink", "YieldParserForScriptLoad", client,
124 TRACE_EVENT_FLAG_FLOW_OUT, "data", 124 TRACE_EVENT_FLAG_FLOW_OUT, "data",
125 getTraceArgsForScriptElement(element, scriptStartPosition)); 125 getTraceArgsForScriptLoaderClient(client, scriptStartPosition));
126 } 126 }
127 } else if (waitingForResources) { 127 } else if (waitingForResources) {
128 TRACE_EVENT_WITH_FLOW1( 128 TRACE_EVENT_WITH_FLOW1(
129 "blink", "YieldParserForScriptBlockingResources", element, 129 "blink", "YieldParserForScriptBlockingResources", client,
130 TRACE_EVENT_FLAG_FLOW_OUT, "data", 130 TRACE_EVENT_FLAG_FLOW_OUT, "data",
131 getTraceArgsForScriptElement(element, scriptStartPosition)); 131 getTraceArgsForScriptLoaderClient(client, scriptStartPosition));
132 } 132 }
133 } 133 }
134 134
135 static KURL documentURLForScriptExecution(Document* document) { 135 static KURL documentURLForScriptExecution(Document* document) {
136 if (!document) 136 if (!document)
137 return KURL(); 137 return KURL();
138 138
139 if (!document->frame()) { 139 if (!document->frame()) {
140 if (document->importsController()) 140 if (document->importsController())
141 return document->url(); 141 return document->url();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 // The parser cannot be unblocked as a microtask requested another 218 // The parser cannot be unblocked as a microtask requested another
219 // resource 219 // resource
220 if (!m_document->isScriptExecutionReady()) 220 if (!m_document->isScriptExecutionReady())
221 return; 221 return;
222 } 222 }
223 } 223 }
224 224
225 TextPosition scriptStartPosition = pendingScript->startingPosition(); 225 TextPosition scriptStartPosition = pendingScript->startingPosition();
226 double scriptParserBlockingTime = 226 double scriptParserBlockingTime =
227 pendingScript->parserBlockingLoadStartTime(); 227 pendingScript->parserBlockingLoadStartTime();
228 Element* element = pendingScript->element(); 228 ScriptLoaderClient* client = pendingScript->scriptLoaderClient();
229 229
230 // 1. "Let the script be the pending parsing-blocking script. 230 // 1. "Let the script be the pending parsing-blocking script.
231 // There is no longer a pending parsing-blocking script." 231 // There is no longer a pending parsing-blocking script."
232 // Clear the pending script before possible re-entrancy from executeScript() 232 // Clear the pending script before possible re-entrancy from executeScript()
233 pendingScript->dispose(); 233 pendingScript->dispose();
234 pendingScript = nullptr; 234 pendingScript = nullptr;
235 235
236 if (pendingScriptType == ScriptStreamer::ParsingBlocking) { 236 if (pendingScriptType == ScriptStreamer::ParsingBlocking) {
237 m_parserBlockingScript = nullptr; 237 m_parserBlockingScript = nullptr;
238 } 238 }
239 239
240 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { 240 if (ScriptLoader* scriptLoader = client->loader()) {
241 // 7. "Increment the parser's script nesting level by one (it should be 241 // 7. "Increment the parser's script nesting level by one (it should be
242 // zero before this step, so this sets it to one)." 242 // zero before this step, so this sets it to one)."
243 HTMLParserReentryPermit::ScriptNestingLevelIncrementer 243 HTMLParserReentryPermit::ScriptNestingLevelIncrementer
244 nestingLevelIncrementer = 244 nestingLevelIncrementer =
245 m_reentryPermit->incrementScriptNestingLevel(); 245 m_reentryPermit->incrementScriptNestingLevel();
246 246
247 IgnoreDestructiveWriteCountIncrementer 247 IgnoreDestructiveWriteCountIncrementer
248 ignoreDestructiveWriteCountIncrementer(m_document); 248 ignoreDestructiveWriteCountIncrementer(m_document);
249 249
250 // 8. "Execute the script." 250 // 8. "Execute the script."
251 if (errorOccurred) { 251 if (errorOccurred) {
252 TRACE_EVENT_WITH_FLOW1( 252 TRACE_EVENT_WITH_FLOW1(
253 "blink", "HTMLParserScriptRunner ExecuteScriptFailed", element, 253 "blink", "HTMLParserScriptRunner ExecuteScriptFailed", client,
254 TRACE_EVENT_FLAG_FLOW_IN, "data", 254 TRACE_EVENT_FLAG_FLOW_IN, "data",
255 getTraceArgsForScriptElement(element, scriptStartPosition)); 255 getTraceArgsForScriptLoaderClient(client, scriptStartPosition));
256 scriptLoader->dispatchErrorEvent(); 256 scriptLoader->dispatchErrorEvent();
257 } else { 257 } else {
258 DCHECK(isExecutingScript()); 258 DCHECK(isExecutingScript());
259 if (scriptParserBlockingTime > 0.0) { 259 if (scriptParserBlockingTime > 0.0) {
260 DocumentParserTiming::from(*m_document) 260 DocumentParserTiming::from(*m_document)
261 .recordParserBlockedOnScriptLoadDuration( 261 .recordParserBlockedOnScriptLoadDuration(
262 monotonicallyIncreasingTime() - scriptParserBlockingTime, 262 monotonicallyIncreasingTime() - scriptParserBlockingTime,
263 scriptLoader->wasCreatedDuringDocumentWrite()); 263 scriptLoader->wasCreatedDuringDocumentWrite());
264 } 264 }
265 if (!doExecuteScript(element, sourceCode, scriptStartPosition)) { 265 if (!doExecuteScript(client, sourceCode, scriptStartPosition)) {
266 scriptLoader->dispatchErrorEvent(); 266 scriptLoader->dispatchErrorEvent();
267 } else { 267 } else {
268 element->dispatchEvent(Event::create(EventTypeNames::load)); 268 client->dispatchLoadEvent();
hiroshige 2017/03/01 00:58:15 Hmm. Conceptually I think we should call scriptLoa
Nate Chapin 2017/03/01 21:34:59 Yeah, I considered calling scriptLoader->dispatchL
269 } 269 }
270 } 270 }
271 271
272 // 9. "Decrement the parser's script nesting level by one. 272 // 9. "Decrement the parser's script nesting level by one.
273 // If the parser's script nesting level is zero 273 // If the parser's script nesting level is zero
274 // (which it always should be at this point), 274 // (which it always should be at this point),
275 // then set the parser pause flag to false." 275 // then set the parser pause flag to false."
276 // This is implemented by ~ScriptNestingLevelIncrementer(). 276 // This is implemented by ~ScriptNestingLevelIncrementer().
277 } 277 }
278 278
279 DCHECK(!isExecutingScript()); 279 DCHECK(!isExecutingScript());
280 } 280 }
281 281
282 void fetchBlockedDocWriteScript(Element* script, 282 void fetchBlockedDocWriteScript(ScriptLoaderClient* client,
283 bool isParserInserted, 283 bool isParserInserted,
284 const TextPosition& scriptStartPosition) { 284 const TextPosition& scriptStartPosition) {
285 DCHECK(script); 285 DCHECK(client);
286 286
287 ScriptLoader* scriptLoader = 287 ScriptLoader* scriptLoader =
288 ScriptLoader::create(script, isParserInserted, false, false); 288 ScriptLoader::create(client, isParserInserted, false, false);
289 DCHECK(scriptLoader); 289 DCHECK(scriptLoader);
290 scriptLoader->setFetchDocWrittenScriptDeferIdle(); 290 scriptLoader->setFetchDocWrittenScriptDeferIdle();
291 scriptLoader->prepareScript(scriptStartPosition); 291 scriptLoader->prepareScript(scriptStartPosition);
292 } 292 }
293 293
294 void emitWarningForDocWriteScripts(const String& url, Document& document) { 294 void emitWarningForDocWriteScripts(const String& url, Document& document) {
295 String message = 295 String message =
296 "The Parser-blocking, cross site (i.e. different eTLD+1) " 296 "The Parser-blocking, cross site (i.e. different eTLD+1) "
297 "script, " + 297 "script, " +
298 url + 298 url +
(...skipping 21 matching lines...) Expand all
320 PendingScript* pendingScript) { 320 PendingScript* pendingScript) {
321 // If the script was blocked as part of document.write intervention, 321 // If the script was blocked as part of document.write intervention,
322 // then send an asynchronous GET request with an interventions header. 322 // then send an asynchronous GET request with an interventions header.
323 323
324 if (!parserBlockingScript()) 324 if (!parserBlockingScript())
325 return; 325 return;
326 326
327 if (parserBlockingScript() != pendingScript) 327 if (parserBlockingScript() != pendingScript)
328 return; 328 return;
329 329
330 Element* element = parserBlockingScript()->element(); 330 ScriptLoaderClient* client = parserBlockingScript()->scriptLoaderClient();
331 331
332 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element); 332 ScriptLoader* scriptLoader = client->loader();
333 if (!scriptLoader || !scriptLoader->disallowedFetchForDocWrittenScript()) 333 if (!scriptLoader || !scriptLoader->disallowedFetchForDocWrittenScript())
334 return; 334 return;
335 335
336 if (!pendingScript->errorOccurred()) { 336 if (!pendingScript->errorOccurred()) {
337 emitWarningForDocWriteScripts(pendingScript->resource()->url().getString(), 337 emitWarningForDocWriteScripts(pendingScript->resource()->url().getString(),
338 *m_document); 338 *m_document);
339 return; 339 return;
340 } 340 }
341 341
342 // Due to dependency violation, not able to check the exact error to be 342 // Due to dependency violation, not able to check the exact error to be
343 // ERR_CACHE_MISS but other errors are rare with 343 // ERR_CACHE_MISS but other errors are rare with
344 // WebCachePolicy::ReturnCacheDataDontLoad. 344 // WebCachePolicy::ReturnCacheDataDontLoad.
345 345
346 emitErrorForDocWriteScripts(pendingScript->resource()->url().getString(), 346 emitErrorForDocWriteScripts(pendingScript->resource()->url().getString(),
347 *m_document); 347 *m_document);
348 TextPosition startingPosition = parserBlockingScript()->startingPosition(); 348 TextPosition startingPosition = parserBlockingScript()->startingPosition();
349 bool isParserInserted = scriptLoader->isParserInserted(); 349 bool isParserInserted = scriptLoader->isParserInserted();
350 // Remove this resource entry from memory cache as the new request 350 // Remove this resource entry from memory cache as the new request
351 // should not join onto this existing entry. 351 // should not join onto this existing entry.
352 memoryCache()->remove(pendingScript->resource()); 352 memoryCache()->remove(pendingScript->resource());
353 fetchBlockedDocWriteScript(element, isParserInserted, startingPosition); 353 fetchBlockedDocWriteScript(client, isParserInserted, startingPosition);
354 } 354 }
355 355
356 void HTMLParserScriptRunner::pendingScriptFinished( 356 void HTMLParserScriptRunner::pendingScriptFinished(
357 PendingScript* pendingScript) { 357 PendingScript* pendingScript) {
358 // Handle cancellations of parser-blocking script loads without 358 // Handle cancellations of parser-blocking script loads without
359 // notifying the host (i.e., parser) if these were initiated by nested 359 // notifying the host (i.e., parser) if these were initiated by nested
360 // document.write()s. The cancellation may have been triggered by 360 // document.write()s. The cancellation may have been triggered by
361 // script execution to signal an abrupt stop (e.g., window.close().) 361 // script execution to signal an abrupt stop (e.g., window.close().)
362 // 362 //
363 // The parser is unprepared to be told, and doesn't need to be. 363 // The parser is unprepared to be told, and doesn't need to be.
(...skipping 10 matching lines...) Expand all
374 } 374 }
375 375
376 // 'An end tag whose tag name is "script"' 376 // 'An end tag whose tag name is "script"'
377 // https://html.spec.whatwg.org/#scriptEndTag 377 // https://html.spec.whatwg.org/#scriptEndTag
378 // 378 //
379 // Script handling lives outside the tree builder to keep each class simple. 379 // Script handling lives outside the tree builder to keep each class simple.
380 void HTMLParserScriptRunner::processScriptElement( 380 void HTMLParserScriptRunner::processScriptElement(
381 Element* scriptElement, 381 Element* scriptElement,
382 const TextPosition& scriptStartPosition) { 382 const TextPosition& scriptStartPosition) {
383 DCHECK(scriptElement); 383 DCHECK(scriptElement);
384 TRACE_EVENT1( 384
385 "blink", "HTMLParserScriptRunner::execute", "data",
386 getTraceArgsForScriptElement(scriptElement, scriptStartPosition));
387 // FIXME: If scripting is disabled, always just return. 385 // FIXME: If scripting is disabled, always just return.
388 386
389 bool hadPreloadScanner = m_host->hasPreloadScanner(); 387 bool hadPreloadScanner = m_host->hasPreloadScanner();
390 388
391 // Initial steps of 'An end tag whose tag name is "script"'. 389 // Initial steps of 'An end tag whose tag name is "script"'.
392 // Try to execute the script given to us. 390 // Try to execute the script given to us.
393 processScriptElementInternal(scriptElement, scriptStartPosition); 391 processScriptElementInternal(scriptElement, scriptStartPosition);
394 392
395 // "At this stage, if there is a pending parsing-blocking script, then:" 393 // "At this stage, if there is a pending parsing-blocking script, then:"
396 if (hasParserBlockingScript()) { 394 if (hasParserBlockingScript()) {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 DCHECK(pendingScript->resource()); 571 DCHECK(pendingScript->resource());
574 572
575 // "Add the element to the end of the list of scripts that will execute 573 // "Add the element to the end of the list of scripts that will execute
576 // when the document has finished parsing associated with the Document 574 // when the document has finished parsing associated with the Document
577 // of the parser that created the element." 575 // of the parser that created the element."
578 m_scriptsToExecuteAfterParsing.append(pendingScript); 576 m_scriptsToExecuteAfterParsing.append(pendingScript);
579 } 577 }
580 578
581 PendingScript* HTMLParserScriptRunner::requestPendingScript( 579 PendingScript* HTMLParserScriptRunner::requestPendingScript(
582 Element* element) const { 580 Element* element) const {
583 ScriptResource* resource = toScriptLoaderIfPossible(element)->resource(); 581 ScriptLoaderClient* client =
582 ScriptLoaderClient::fromElementIfPossible(element);
hiroshige 2017/03/01 00:58:15 Probably we can remove fromElementIfPossible() cal
Nate Chapin 2017/03/01 21:35:00 Possibly, but that requires changing PendingScript
hiroshige 2017/03/06 22:54:03 Acknowledged.
583 ScriptResource* resource = client->loader()->resource();
584 // Here |resource| should be non-null. If it were nullptr, 584 // Here |resource| should be non-null. If it were nullptr,
585 // ScriptLoader::fetchScript() should have returned false and 585 // ScriptLoader::fetchScript() should have returned false and
586 // thus the control shouldn't have reached here. 586 // thus the control shouldn't have reached here.
587 CHECK(resource); 587 CHECK(resource);
588 return PendingScript::create(element, resource); 588 return PendingScript::create(client, resource);
589 } 589 }
590 590
591 // The initial steps for 'An end tag whose tag name is "script"' 591 // The initial steps for 'An end tag whose tag name is "script"'
592 // https://html.spec.whatwg.org/#scriptEndTag 592 // https://html.spec.whatwg.org/#scriptEndTag
593 void HTMLParserScriptRunner::processScriptElementInternal( 593 void HTMLParserScriptRunner::processScriptElementInternal(
594 Element* script, 594 Element* script,
595 const TextPosition& scriptStartPosition) { 595 const TextPosition& scriptStartPosition) {
596 DCHECK(m_document); 596 DCHECK(m_document);
597 DCHECK(!hasParserBlockingScript()); 597 DCHECK(!hasParserBlockingScript());
598 { 598 {
599 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(script); 599 ScriptLoaderClient* client =
600 ScriptLoaderClient::fromElementIfPossible(script);
601 if (!client)
hiroshige 2017/03/01 00:58:15 Shouldn't |client| always non-null because we expe
Nate Chapin 2017/03/01 21:34:59 It should be, I was just copying the pattern of th
602 return;
603 ScriptLoader* scriptLoader = client->loader();
600 604
601 // This contains both a DCHECK and a null check since we should not 605 // This contains both a DCHECK and a null check since we should not
602 // be getting into the case of a null script element, but seem to be from 606 // be getting into the case of a null script element, but seem to be from
603 // time to time. The assertion is left in to help find those cases and 607 // time to time. The assertion is left in to help find those cases and
604 // is being tracked by <https://bugs.webkit.org/show_bug.cgi?id=60559>. 608 // is being tracked by <https://bugs.webkit.org/show_bug.cgi?id=60559>.
605 DCHECK(scriptLoader); 609 DCHECK(scriptLoader);
606 if (!scriptLoader) 610 if (!scriptLoader)
607 return; 611 return;
608 612
613 TRACE_EVENT1(
614 "blink", "HTMLParserScriptRunner::execute", "data",
615 getTraceArgsForScriptLoaderClient(client, scriptStartPosition));
609 DCHECK(scriptLoader->isParserInserted()); 616 DCHECK(scriptLoader->isParserInserted());
610 617
611 if (!isExecutingScript()) 618 if (!isExecutingScript())
612 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); 619 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate());
613 620
614 // "Let the old insertion point have the same value as the current 621 // "Let the old insertion point have the same value as the current
615 // insertion point. 622 // insertion point.
616 // Let the insertion point be just before the next input character." 623 // Let the insertion point be just before the next input character."
617 InsertionPointRecord insertionPointRecord(m_host->inputStream()); 624 InsertionPointRecord insertionPointRecord(m_host->inputStream());
618 625
(...skipping 18 matching lines...) Expand all
637 } else if (scriptLoader->readyToBeParserExecuted()) { 644 } else if (scriptLoader->readyToBeParserExecuted()) {
638 // 5th Clause of Step 23. 645 // 5th Clause of Step 23.
639 // "If ... it's an HTML parser 646 // "If ... it's an HTML parser
640 // whose script nesting level is not greater than one" 647 // whose script nesting level is not greater than one"
641 if (m_reentryPermit->scriptNestingLevel() == 1u) { 648 if (m_reentryPermit->scriptNestingLevel() == 1u) {
642 // "The element is the pending parsing-blocking script of the 649 // "The element is the pending parsing-blocking script of the
643 // Document of the parser that created the element. 650 // Document of the parser that created the element.
644 // (There can only be one such script per Document at a time.)" 651 // (There can only be one such script per Document at a time.)"
645 CHECK(!m_parserBlockingScript); 652 CHECK(!m_parserBlockingScript);
646 m_parserBlockingScript = 653 m_parserBlockingScript =
647 PendingScript::create(script, scriptStartPosition); 654 PendingScript::create(client, scriptStartPosition);
648 } else { 655 } else {
649 // 6th Clause of Step 23. 656 // 6th Clause of Step 23.
650 // "Immediately execute the script block, 657 // "Immediately execute the script block,
651 // even if other scripts are already executing." 658 // even if other scripts are already executing."
652 // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript(). 659 // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript().
653 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u); 660 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u);
654 if (m_parserBlockingScript) 661 if (m_parserBlockingScript)
655 m_parserBlockingScript->dispose(); 662 m_parserBlockingScript->dispose();
656 m_parserBlockingScript = nullptr; 663 m_parserBlockingScript = nullptr;
657 ScriptSourceCode sourceCode(script->textContent(), 664 ScriptSourceCode sourceCode(script->textContent(),
658 documentURLForScriptExecution(m_document), 665 documentURLForScriptExecution(m_document),
659 scriptStartPosition); 666 scriptStartPosition);
660 doExecuteScript(script, sourceCode, scriptStartPosition); 667 doExecuteScript(client, sourceCode, scriptStartPosition);
661 } 668 }
662 } else { 669 } else {
663 // 2nd Clause of Step 23. 670 // 2nd Clause of Step 23.
664 requestParsingBlockingScript(script); 671 requestParsingBlockingScript(script);
665 } 672 }
666 673
667 // "Decrement the parser's script nesting level by one. 674 // "Decrement the parser's script nesting level by one.
668 // If the parser's script nesting level is zero, then set the parser 675 // If the parser's script nesting level is zero, then set the parser
669 // pause flag to false." 676 // pause flag to false."
670 // Implemented by ~ScriptNestingLevelIncrementer(). 677 // Implemented by ~ScriptNestingLevelIncrementer().
671 678
672 // "Let the insertion point have the value of the old insertion point." 679 // "Let the insertion point have the value of the old insertion point."
673 // Implemented by ~InsertionPointRecord(). 680 // Implemented by ~InsertionPointRecord().
674 } 681 }
675 } 682 }
676 683
677 DEFINE_TRACE(HTMLParserScriptRunner) { 684 DEFINE_TRACE(HTMLParserScriptRunner) {
678 visitor->trace(m_document); 685 visitor->trace(m_document);
679 visitor->trace(m_host); 686 visitor->trace(m_host);
680 visitor->trace(m_parserBlockingScript); 687 visitor->trace(m_parserBlockingScript);
681 visitor->trace(m_scriptsToExecuteAfterParsing); 688 visitor->trace(m_scriptsToExecuteAfterParsing);
682 PendingScriptClient::trace(visitor); 689 PendingScriptClient::trace(visitor);
683 } 690 }
684 691
685 } // namespace blink 692 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698