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

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

Issue 2653923008: Reland of Split PendingScript into PendingScript and ClassicPendingScript (Closed)
Patch Set: Fix file header Created 3 years, 8 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 13 matching lines...) Expand all
24 */ 24 */
25 25
26 #include "core/html/parser/HTMLParserScriptRunner.h" 26 #include "core/html/parser/HTMLParserScriptRunner.h"
27 27
28 #include <inttypes.h> 28 #include <inttypes.h>
29 #include <memory> 29 #include <memory>
30 #include "bindings/core/v8/Microtask.h" 30 #include "bindings/core/v8/Microtask.h"
31 #include "bindings/core/v8/ScriptSourceCode.h" 31 #include "bindings/core/v8/ScriptSourceCode.h"
32 #include "bindings/core/v8/V8Binding.h" 32 #include "bindings/core/v8/V8Binding.h"
33 #include "bindings/core/v8/V8PerIsolateData.h" 33 #include "bindings/core/v8/V8PerIsolateData.h"
34 #include "core/dom/ClassicPendingScript.h"
34 #include "core/dom/ClassicScript.h" 35 #include "core/dom/ClassicScript.h"
35 #include "core/dom/DocumentParserTiming.h" 36 #include "core/dom/DocumentParserTiming.h"
36 #include "core/dom/Element.h" 37 #include "core/dom/Element.h"
37 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" 38 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
38 #include "core/dom/ScriptLoader.h" 39 #include "core/dom/ScriptLoader.h"
39 #include "core/dom/TaskRunnerHelper.h" 40 #include "core/dom/TaskRunnerHelper.h"
40 #include "core/events/Event.h" 41 #include "core/events/Event.h"
41 #include "core/frame/LocalFrame.h" 42 #include "core/frame/LocalFrame.h"
42 #include "core/html/parser/HTMLInputStream.h" 43 #include "core/html/parser/HTMLInputStream.h"
43 #include "core/html/parser/HTMLParserScriptRunnerHost.h" 44 #include "core/html/parser/HTMLParserScriptRunnerHost.h"
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 if (parserBlockingScript() != pendingScript) 329 if (parserBlockingScript() != pendingScript)
329 return; 330 return;
330 331
331 ScriptElementBase* element = parserBlockingScript()->element(); 332 ScriptElementBase* element = parserBlockingScript()->element();
332 333
333 ScriptLoader* scriptLoader = element->loader(); 334 ScriptLoader* scriptLoader = element->loader();
334 if (!scriptLoader || !scriptLoader->disallowedFetchForDocWrittenScript()) 335 if (!scriptLoader || !scriptLoader->disallowedFetchForDocWrittenScript())
335 return; 336 return;
336 337
337 if (!pendingScript->errorOccurred()) { 338 if (!pendingScript->errorOccurred()) {
338 emitWarningForDocWriteScripts(pendingScript->resource()->url().getString(), 339 emitWarningForDocWriteScripts(pendingScript->url().getString(),
339 *m_document); 340 *m_document);
340 return; 341 return;
341 } 342 }
342 343
343 // Due to dependency violation, not able to check the exact error to be 344 // Due to dependency violation, not able to check the exact error to be
344 // ERR_CACHE_MISS but other errors are rare with 345 // ERR_CACHE_MISS but other errors are rare with
345 // WebCachePolicy::ReturnCacheDataDontLoad. 346 // WebCachePolicy::ReturnCacheDataDontLoad.
346 347
347 emitErrorForDocWriteScripts(pendingScript->resource()->url().getString(), 348 emitErrorForDocWriteScripts(pendingScript->url().getString(), *m_document);
348 *m_document);
349 TextPosition startingPosition = parserBlockingScript()->startingPosition(); 349 TextPosition startingPosition = parserBlockingScript()->startingPosition();
350 bool isParserInserted = scriptLoader->isParserInserted(); 350 bool isParserInserted = scriptLoader->isParserInserted();
351 // Remove this resource entry from memory cache as the new request 351 // Remove this resource entry from memory cache as the new request
352 // should not join onto this existing entry. 352 // should not join onto this existing entry.
353 memoryCache()->remove(pendingScript->resource()); 353 // memoryCache()->remove(pendingScript->resource());
354 fetchBlockedDocWriteScript(element, isParserInserted, startingPosition); 354 fetchBlockedDocWriteScript(element, isParserInserted, startingPosition);
355 } 355 }
356 356
357 void HTMLParserScriptRunner::pendingScriptFinished( 357 void HTMLParserScriptRunner::pendingScriptFinished(
358 PendingScript* pendingScript) { 358 PendingScript* pendingScript) {
359 // Handle cancellations of parser-blocking script loads without 359 // Handle cancellations of parser-blocking script loads without
360 // notifying the host (i.e., parser) if these were initiated by nested 360 // notifying the host (i.e., parser) if these were initiated by nested
361 // document.write()s. The cancellation may have been triggered by 361 // document.write()s. The cancellation may have been triggered by
362 // script execution to signal an abrupt stop (e.g., window.close().) 362 // script execution to signal an abrupt stop (e.g., window.close().)
363 // 363 //
364 // The parser is unprepared to be told, and doesn't need to be. 364 // The parser is unprepared to be told, and doesn't need to be.
365 if (isExecutingScript() && pendingScript->resource()->wasCanceled()) { 365 if (isExecutingScript() && pendingScript->wasCanceled()) {
366 pendingScript->dispose(); 366 pendingScript->dispose();
367 367
368 if (pendingScript == parserBlockingScript()) { 368 if (pendingScript == parserBlockingScript()) {
369 m_parserBlockingScript = nullptr; 369 m_parserBlockingScript = nullptr;
370 } else { 370 } else {
371 CHECK_EQ(pendingScript, m_scriptsToExecuteAfterParsing.front()); 371 CHECK_EQ(pendingScript, m_scriptsToExecuteAfterParsing.front());
372 372
373 // TODO(hiroshige): Remove this CHECK() before going to beta. 373 // TODO(hiroshige): Remove this CHECK() before going to beta.
374 // This is only to make clusterfuzz to find a test case that executes 374 // This is only to make clusterfuzz to find a test case that executes
375 // this code path. 375 // this code path.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 // Step 3 of https://html.spec.whatwg.org/#the-end: 497 // Step 3 of https://html.spec.whatwg.org/#the-end:
498 // "If the list of scripts that will execute when the document has 498 // "If the list of scripts that will execute when the document has
499 // finished parsing is not empty, run these substeps:" 499 // finished parsing is not empty, run these substeps:"
500 bool HTMLParserScriptRunner::executeScriptsWaitingForParsing() { 500 bool HTMLParserScriptRunner::executeScriptsWaitingForParsing() {
501 TRACE_EVENT0("blink", 501 TRACE_EVENT0("blink",
502 "HTMLParserScriptRunner::executeScriptsWaitingForParsing"); 502 "HTMLParserScriptRunner::executeScriptsWaitingForParsing");
503 503
504 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { 504 while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
505 DCHECK(!isExecutingScript()); 505 DCHECK(!isExecutingScript());
506 DCHECK(!hasParserBlockingScript()); 506 DCHECK(!hasParserBlockingScript());
507 DCHECK(m_scriptsToExecuteAfterParsing.front()->resource()); 507 DCHECK(m_scriptsToExecuteAfterParsing.front()->isExternal());
508 508
509 // 1. "Spin the event loop until the first script in the list of scripts 509 // 1. "Spin the event loop until the first script in the list of scripts
510 // that will execute when the document has finished parsing 510 // that will execute when the document has finished parsing
511 // has its "ready to be parser-executed" flag set and 511 // has its "ready to be parser-executed" flag set and
512 // the parser's Document has no style sheet that is blocking scripts." 512 // the parser's Document has no style sheet that is blocking scripts."
513 // TODO(hiroshige): Is the latter part checked anywhere? 513 // TODO(hiroshige): Is the latter part checked anywhere?
514 if (!m_scriptsToExecuteAfterParsing.front()->isReady()) { 514 if (!m_scriptsToExecuteAfterParsing.front()->isReady()) {
515 m_scriptsToExecuteAfterParsing.front()->watchForLoad(this); 515 m_scriptsToExecuteAfterParsing.front()->watchForLoad(this);
516 traceParserBlockingScript(m_scriptsToExecuteAfterParsing.front().get(), 516 traceParserBlockingScript(m_scriptsToExecuteAfterParsing.front().get(),
517 !m_document->isScriptExecutionReady()); 517 !m_document->isScriptExecutionReady());
(...skipping 24 matching lines...) Expand all
542 // 2nd Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script 542 // 2nd Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script
543 void HTMLParserScriptRunner::requestParsingBlockingScript(Element* element) { 543 void HTMLParserScriptRunner::requestParsingBlockingScript(Element* element) {
544 // "The element is the pending parsing-blocking script of the Document of 544 // "The element is the pending parsing-blocking script of the Document of
545 // the parser that created the element. 545 // the parser that created the element.
546 // (There can only be one such script per Document at a time.)" 546 // (There can only be one such script per Document at a time.)"
547 CHECK(!parserBlockingScript()); 547 CHECK(!parserBlockingScript());
548 m_parserBlockingScript = requestPendingScript(element); 548 m_parserBlockingScript = requestPendingScript(element);
549 if (!parserBlockingScript()) 549 if (!parserBlockingScript())
550 return; 550 return;
551 551
552 DCHECK(parserBlockingScript()->resource());
553
554 // We only care about a load callback if resource is not already in the cache. 552 // We only care about a load callback if resource is not already in the cache.
555 // Callers will attempt to run the m_parserBlockingScript if possible before 553 // Callers will attempt to run the m_parserBlockingScript if possible before
556 // returning control to the parser. 554 // returning control to the parser.
557 if (!parserBlockingScript()->isReady()) { 555 if (!parserBlockingScript()->isReady()) {
558 m_parserBlockingScript->startStreamingIfPossible( 556 m_parserBlockingScript->startStreamingIfPossible(
559 m_document, ScriptStreamer::ParsingBlocking); 557 m_document, ScriptStreamer::ParsingBlocking);
560 m_parserBlockingScript->watchForLoad(this); 558 m_parserBlockingScript->watchForLoad(this);
561 } 559 }
562 } 560 }
563 561
564 // 1st Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script 562 // 1st Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script
565 void HTMLParserScriptRunner::requestDeferredScript(Element* element) { 563 void HTMLParserScriptRunner::requestDeferredScript(Element* element) {
566 PendingScript* pendingScript = requestPendingScript(element); 564 PendingScript* pendingScript = requestPendingScript(element);
567 if (!pendingScript) 565 if (!pendingScript)
568 return; 566 return;
569 567
570 if (!pendingScript->isReady()) { 568 if (!pendingScript->isReady()) {
571 pendingScript->startStreamingIfPossible(m_document, 569 pendingScript->startStreamingIfPossible(m_document,
572 ScriptStreamer::Deferred); 570 ScriptStreamer::Deferred);
573 } 571 }
574 572
575 DCHECK(pendingScript->resource());
576
577 // "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
578 // when the document has finished parsing associated with the Document 574 // when the document has finished parsing associated with the Document
579 // of the parser that created the element." 575 // of the parser that created the element."
580 m_scriptsToExecuteAfterParsing.push_back(pendingScript); 576 m_scriptsToExecuteAfterParsing.push_back(pendingScript);
581 } 577 }
582 578
583 PendingScript* HTMLParserScriptRunner::requestPendingScript( 579 PendingScript* HTMLParserScriptRunner::requestPendingScript(
584 Element* element) const { 580 Element* element) const {
585 ScriptElementBase* scriptElement = 581 ScriptElementBase* scriptElement =
586 ScriptElementBase::fromElementIfPossible(element); 582 ScriptElementBase::fromElementIfPossible(element);
587 ScriptResource* resource = scriptElement->loader()->resource(); 583 ScriptResource* resource = scriptElement->loader()->resource();
588 // Here |resource| should be non-null. If it were nullptr, 584 // Here |resource| should be non-null. If it were nullptr,
589 // ScriptLoader::fetchScript() should have returned false and 585 // ScriptLoader::fetchScript() should have returned false and
590 // thus the control shouldn't have reached here. 586 // thus the control shouldn't have reached here.
591 CHECK(resource); 587 CHECK(resource);
592 return PendingScript::create(scriptElement, resource); 588 ClassicPendingScript* pendingScript =
589 ClassicPendingScript::create(scriptElement, resource);
590 DCHECK(pendingScript->resource());
591 return pendingScript;
593 } 592 }
594 593
595 // The initial steps for 'An end tag whose tag name is "script"' 594 // The initial steps for 'An end tag whose tag name is "script"'
596 // https://html.spec.whatwg.org/#scriptEndTag 595 // https://html.spec.whatwg.org/#scriptEndTag
597 void HTMLParserScriptRunner::processScriptElementInternal( 596 void HTMLParserScriptRunner::processScriptElementInternal(
598 Element* script, 597 Element* script,
599 const TextPosition& scriptStartPosition) { 598 const TextPosition& scriptStartPosition) {
600 DCHECK(m_document); 599 DCHECK(m_document);
601 DCHECK(!hasParserBlockingScript()); 600 DCHECK(!hasParserBlockingScript());
602 { 601 {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 } else if (scriptLoader->readyToBeParserExecuted()) { 639 } else if (scriptLoader->readyToBeParserExecuted()) {
641 // 5th Clause of Step 23. 640 // 5th Clause of Step 23.
642 // "If ... it's an HTML parser 641 // "If ... it's an HTML parser
643 // whose script nesting level is not greater than one" 642 // whose script nesting level is not greater than one"
644 if (m_reentryPermit->scriptNestingLevel() == 1u) { 643 if (m_reentryPermit->scriptNestingLevel() == 1u) {
645 // "The element is the pending parsing-blocking script of the 644 // "The element is the pending parsing-blocking script of the
646 // Document of the parser that created the element. 645 // Document of the parser that created the element.
647 // (There can only be one such script per Document at a time.)" 646 // (There can only be one such script per Document at a time.)"
648 CHECK(!m_parserBlockingScript); 647 CHECK(!m_parserBlockingScript);
649 m_parserBlockingScript = 648 m_parserBlockingScript =
650 PendingScript::create(element, scriptStartPosition); 649 ClassicPendingScript::create(element, scriptStartPosition);
651 } else { 650 } else {
652 // 6th Clause of Step 23. 651 // 6th Clause of Step 23.
653 // "Immediately execute the script block, 652 // "Immediately execute the script block,
654 // even if other scripts are already executing." 653 // even if other scripts are already executing."
655 // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript(). 654 // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript().
656 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u); 655 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u);
657 if (m_parserBlockingScript) 656 if (m_parserBlockingScript)
658 m_parserBlockingScript->dispose(); 657 m_parserBlockingScript->dispose();
659 m_parserBlockingScript = nullptr; 658 m_parserBlockingScript = nullptr;
660 ScriptSourceCode sourceCode(script->textContent(), 659 ScriptSourceCode sourceCode(script->textContent(),
(...skipping 19 matching lines...) Expand all
680 679
681 DEFINE_TRACE(HTMLParserScriptRunner) { 680 DEFINE_TRACE(HTMLParserScriptRunner) {
682 visitor->trace(m_document); 681 visitor->trace(m_document);
683 visitor->trace(m_host); 682 visitor->trace(m_host);
684 visitor->trace(m_parserBlockingScript); 683 visitor->trace(m_parserBlockingScript);
685 visitor->trace(m_scriptsToExecuteAfterParsing); 684 visitor->trace(m_scriptsToExecuteAfterParsing);
686 PendingScriptClient::trace(visitor); 685 PendingScriptClient::trace(visitor);
687 } 686 }
688 687
689 } // namespace blink 688 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698