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

Side by Side Diff: third_party/WebKit/Source/core/dom/ScriptLoader.cpp

Issue 2695713015: WIP: Reland CompiledScript, prototype compiling in a separate task.
Patch Set: allow compile to fail, disallow restreaming (hack) 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) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights
6 * reserved. 6 * reserved.
7 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 7 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 104
105 ScriptLoader::~ScriptLoader() {} 105 ScriptLoader::~ScriptLoader() {}
106 106
107 DEFINE_TRACE(ScriptLoader) { 107 DEFINE_TRACE(ScriptLoader) {
108 visitor->trace(m_element); 108 visitor->trace(m_element);
109 visitor->trace(m_resource); 109 visitor->trace(m_resource);
110 visitor->trace(m_pendingScript); 110 visitor->trace(m_pendingScript);
111 PendingScriptClient::trace(visitor); 111 PendingScriptClient::trace(visitor);
112 } 112 }
113 113
114 // static
115 AccessControlStatus ScriptLoader::accessControlStatusForScript(
116 bool isExternalScript,
117 const ScriptResource* resource,
118 const SecurityOrigin* scriptElementOrigin) {
119 if (!isExternalScript)
120 return SharableCrossOrigin;
121
122 // TODO(jbroman): DCHECK(resource)?
123 if (!resource)
124 return NotSharableCrossOrigin;
125
126 const auto& response = resource->response();
127 if (response.wasFetchedViaServiceWorker()) {
128 return response.serviceWorkerResponseType() ==
129 WebServiceWorkerResponseTypeOpaque
130 ? OpaqueResource
131 : SharableCrossOrigin;
132 }
133
134 return resource->passesAccessControlCheck(scriptElementOrigin)
135 ? SharableCrossOrigin
136 : NotSharableCrossOrigin;
137 }
138
114 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { 139 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() {
115 DCHECK(!m_createdDuringDocumentWrite); 140 DCHECK(!m_createdDuringDocumentWrite);
116 m_documentWriteIntervention = 141 m_documentWriteIntervention =
117 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; 142 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle;
118 } 143 }
119 144
120 void ScriptLoader::didNotifySubtreeInsertionsToDocument() { 145 void ScriptLoader::didNotifySubtreeInsertionsToDocument() {
121 if (!m_parserInserted) 146 if (!m_parserInserted)
122 prepareScript(); // FIXME: Provide a real starting line number here. 147 prepareScript(); // FIXME: Provide a real starting line number here.
123 } 148 }
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 ? (isText ? UseCounter::SameOriginTextScript 678 ? (isText ? UseCounter::SameOriginTextScript
654 : isApplication ? UseCounter::SameOriginApplicationScript 679 : isApplication ? UseCounter::SameOriginApplicationScript
655 : UseCounter::SameOriginOtherScript) 680 : UseCounter::SameOriginOtherScript)
656 : (isText ? UseCounter::CrossOriginTextScript 681 : (isText ? UseCounter::CrossOriginTextScript
657 : isApplication ? UseCounter::CrossOriginApplicationScript 682 : isApplication ? UseCounter::CrossOriginApplicationScript
658 : UseCounter::CrossOriginOtherScript); 683 : UseCounter::CrossOriginOtherScript);
659 684
660 UseCounter::count(frame, feature); 685 UseCounter::count(frame, feature);
661 } 686 }
662 687
663 bool ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) { 688 bool ScriptLoader::executeScript(const ScriptSourceCode& sourceCode,
689 CompiledScript* compiledScript) {
664 double scriptExecStartTime = monotonicallyIncreasingTime(); 690 double scriptExecStartTime = monotonicallyIncreasingTime();
665 bool result = doExecuteScript(sourceCode); 691 bool result = doExecuteScript(sourceCode, compiledScript);
666 692
667 // NOTE: we do not check m_willBeParserExecuted here, since 693 // NOTE: we do not check m_willBeParserExecuted here, since
668 // m_willBeParserExecuted is false for inline scripts, and we want to 694 // m_willBeParserExecuted is false for inline scripts, and we want to
669 // include inline script execution time as part of parser blocked script 695 // include inline script execution time as part of parser blocked script
670 // execution time. 696 // execution time.
671 if (m_asyncExecType == ScriptRunner::None) 697 if (m_asyncExecType == ScriptRunner::None)
672 DocumentParserTiming::from(m_element->document()) 698 DocumentParserTiming::from(m_element->document())
673 .recordParserBlockedOnScriptExecutionDuration( 699 .recordParserBlockedOnScriptExecutionDuration(
674 monotonicallyIncreasingTime() - scriptExecStartTime, 700 monotonicallyIncreasingTime() - scriptExecStartTime,
675 wasCreatedDuringDocumentWrite()); 701 wasCreatedDuringDocumentWrite());
676 return result; 702 return result;
677 } 703 }
678 704
679 // https://html.spec.whatwg.org/#execute-the-script-block 705 // https://html.spec.whatwg.org/#execute-the-script-block
680 // with additional support for HTML imports. 706 // with additional support for HTML imports.
681 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(), 707 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(),
682 // i.e. load/error events are dispatched by the caller. 708 // i.e. load/error events are dispatched by the caller.
683 // Steps 3--7 are implemented here in doExecuteScript(). 709 // Steps 3--7 are implemented here in doExecuteScript().
684 // TODO(hiroshige): Move event dispatching code to doExecuteScript(). 710 // TODO(hiroshige): Move event dispatching code to doExecuteScript().
685 bool ScriptLoader::doExecuteScript(const ScriptSourceCode& sourceCode) { 711 bool ScriptLoader::doExecuteScript(const ScriptSourceCode& sourceCode,
712 CompiledScript* compiledScript) {
686 DCHECK(m_alreadyStarted); 713 DCHECK(m_alreadyStarted);
687 714
688 if (sourceCode.isEmpty()) 715 if (sourceCode.isEmpty())
689 return true; 716 return true;
690 717
691 Document* elementDocument = &(m_element->document()); 718 Document* elementDocument = &(m_element->document());
692 Document* contextDocument = elementDocument->contextDocument(); 719 Document* contextDocument = elementDocument->contextDocument();
693 if (!contextDocument) 720 if (!contextDocument)
694 return true; 721 return true;
695 722
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 else if (mimeType.startsWith("video/")) 771 else if (mimeType.startsWith("video/"))
745 UseCounter::count(frame, UseCounter::BlockedSniffingVideoToScript); 772 UseCounter::count(frame, UseCounter::BlockedSniffingVideoToScript);
746 else if (mimeType == "text/csv") 773 else if (mimeType == "text/csv")
747 UseCounter::count(frame, UseCounter::BlockedSniffingCSVToScript); 774 UseCounter::count(frame, UseCounter::BlockedSniffingCSVToScript);
748 return false; 775 return false;
749 } 776 }
750 777
751 logScriptMIMEType(frame, resource, mimeType); 778 logScriptMIMEType(frame, resource, mimeType);
752 } 779 }
753 780
754 AccessControlStatus accessControlStatus = NotSharableCrossOrigin; 781 AccessControlStatus accessControlStatus =
755 if (!m_isExternalScript) { 782 accessControlStatusForScript(m_isExternalScript, sourceCode.resource(),
756 accessControlStatus = SharableCrossOrigin; 783 elementDocument->getSecurityOrigin());
757 } else if (sourceCode.resource()) {
758 if (sourceCode.resource()->response().wasFetchedViaServiceWorker()) {
759 if (sourceCode.resource()->response().serviceWorkerResponseType() ==
760 WebServiceWorkerResponseTypeOpaque)
761 accessControlStatus = OpaqueResource;
762 else
763 accessControlStatus = SharableCrossOrigin;
764 } else if (sourceCode.resource()->passesAccessControlCheck(
765 m_element->document().getSecurityOrigin())) {
766 accessControlStatus = SharableCrossOrigin;
767 }
768 }
769 784
770 const bool isImportedScript = contextDocument != elementDocument; 785 const bool isImportedScript = contextDocument != elementDocument;
771 786
772 // 3. "If the script is from an external file, 787 // 3. "If the script is from an external file,
773 // or the script's type is module", 788 // or the script's type is module",
774 // then increment the ignore-destructive-writes counter of the 789 // then increment the ignore-destructive-writes counter of the
775 // script element's node document. Let neutralized doc be that Document." 790 // script element's node document. Let neutralized doc be that Document."
776 // TODO(hiroshige): Implement "module" case. 791 // TODO(hiroshige): Implement "module" case.
777 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer( 792 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(
778 m_isExternalScript || isImportedScript ? contextDocument : 0); 793 m_isExternalScript || isImportedScript ? contextDocument : 0);
779 794
780 // 4. "Let old script element be the value to which the script element's 795 // 4. "Let old script element be the value to which the script element's
781 // node document's currentScript object was most recently set." 796 // node document's currentScript object was most recently set."
782 // This is implemented as push/popCurrentScript(). 797 // This is implemented as push/popCurrentScript().
783 798
784 // 5. "Switch on the script's type:" 799 // 5. "Switch on the script's type:"
785 // - "classic": 800 // - "classic":
786 // 1. "If the script element's root is not a shadow root, 801 // 1. "If the script element's root is not a shadow root,
787 // then set the script element's node document's currentScript 802 // then set the script element's node document's currentScript
788 // attribute to the script element. Otherwise, set it to null." 803 // attribute to the script element. Otherwise, set it to null."
789 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) 804 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element))
790 contextDocument->pushCurrentScript(m_element); 805 contextDocument->pushCurrentScript(m_element);
791 806
792 // 2. "Run the classic script given by the script's script." 807 // 2. "Run the classic script given by the script's script."
793 // Note: This is where the script is compiled and actually executed. 808 // Note: This is where the script is compiled and actually executed.
794 frame->script().executeScriptInMainWorld(sourceCode, accessControlStatus); 809 if (compiledScript) {
810 frame->script().executeScriptInMainWorld(*compiledScript);
811 } else {
812 frame->script().executeScriptInMainWorld(sourceCode, accessControlStatus);
813 }
795 814
796 // - "module": 815 // - "module":
797 // TODO(hiroshige): Implement this. 816 // TODO(hiroshige): Implement this.
798 817
799 // 6. "Set the script element's node document's currentScript attribute 818 // 6. "Set the script element's node document's currentScript attribute
800 // to old script element." 819 // to old script element."
801 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) { 820 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) {
802 DCHECK(contextDocument->currentScript() == m_element); 821 DCHECK(contextDocument->currentScript() == m_element);
803 contextDocument->popCurrentScript(); 822 contextDocument->popCurrentScript();
804 } 823 }
805 824
806 return true; 825 return true;
807 826
808 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, 827 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc,
809 // if it was incremented in the earlier step." 828 // if it was incremented in the earlier step."
810 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. 829 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer.
811 } 830 }
812 831
813 void ScriptLoader::execute() { 832 void ScriptLoader::execute() {
814 DCHECK(!m_willBeParserExecuted); 833 DCHECK(!m_willBeParserExecuted);
815 DCHECK(m_asyncExecType != ScriptRunner::None); 834 DCHECK(m_asyncExecType != ScriptRunner::None);
816 DCHECK(m_pendingScript->resource()); 835 DCHECK(m_pendingScript->resource());
817 bool errorOccurred = false; 836 bool errorOccurred = false;
818 ScriptSourceCode source = m_pendingScript->getSource(KURL(), errorOccurred); 837 ScriptSourceCode source = m_pendingScript->getSource(KURL(), errorOccurred);
838 CompiledScript* compiledScript = m_pendingScript->getCompiledScript();
819 detachPendingScript(); 839 detachPendingScript();
820 if (errorOccurred) { 840 if (errorOccurred) {
821 dispatchErrorEvent(); 841 dispatchErrorEvent();
822 } else if (!m_resource->wasCanceled()) { 842 } else if (!m_resource->wasCanceled()) {
823 if (executeScript(source)) 843 if (executeScript(source, compiledScript))
824 dispatchLoadEvent(); 844 dispatchLoadEvent();
825 else 845 else
826 dispatchErrorEvent(); 846 dispatchErrorEvent();
827 } 847 }
828 m_resource = nullptr; 848 m_resource = nullptr;
829 } 849 }
830 850
831 void ScriptLoader::pendingScriptFinished(PendingScript* pendingScript) { 851 void ScriptLoader::pendingScriptFinished(PendingScript* pendingScript) {
852 LOG(ERROR) << "Finished loading pending script of size "
853 << pendingScript->resource()->size();
832 DCHECK(!m_willBeParserExecuted); 854 DCHECK(!m_willBeParserExecuted);
833 DCHECK_EQ(m_pendingScript, pendingScript); 855 DCHECK_EQ(m_pendingScript, pendingScript);
834 DCHECK_EQ(pendingScript->resource(), m_resource); 856 DCHECK_EQ(pendingScript->resource(), m_resource);
835 857
836 // We do not need this script in the memory cache. The primary goals of 858 // We do not need this script in the memory cache. The primary goals of
837 // sending this fetch request are to let the third party server know 859 // sending this fetch request are to let the third party server know
838 // about the document.write scripts intervention and populate the http 860 // about the document.write scripts intervention and populate the http
839 // cache for subsequent uses. 861 // cache for subsequent uses.
840 if (m_documentWriteIntervention == 862 if (m_documentWriteIntervention ==
841 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { 863 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 if (isHTMLScriptLoader(element)) 937 if (isHTMLScriptLoader(element))
916 return toHTMLScriptElement(element)->loader(); 938 return toHTMLScriptElement(element)->loader();
917 939
918 if (isSVGScriptLoader(element)) 940 if (isSVGScriptLoader(element))
919 return toSVGScriptElement(element)->loader(); 941 return toSVGScriptElement(element)->loader();
920 942
921 return 0; 943 return 0;
922 } 944 }
923 945
924 } // namespace blink 946 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698