OLD | NEW |
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 if (HTMLParserThread::shared()) | 95 if (HTMLParserThread::shared()) |
96 return &HTMLParserThread::shared()->platformThread(); | 96 return &HTMLParserThread::shared()->platformThread(); |
97 | 97 |
98 return nullptr; | 98 return nullptr; |
99 } | 99 } |
100 | 100 |
101 private: | 101 private: |
102 WeakPtr<BackgroundHTMLParser> m_backgroundParser; | 102 WeakPtr<BackgroundHTMLParser> m_backgroundParser; |
103 }; | 103 }; |
104 | 104 |
105 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors
) | 105 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors
, ParserSynchronizationPolicy syncPolicy) |
106 : ScriptableDocumentParser(document) | 106 : ScriptableDocumentParser(document) |
107 , m_options(&document) | 107 , m_options(&document) |
108 , m_token(nullptr) | 108 , m_token(syncPolicy == ForceSynchronousParsing ? adoptPtr(new HTMLToken) :
nullptr) |
109 , m_tokenizer(nullptr) | 109 , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create(
m_options) : nullptr) |
110 , m_scriptRunner(HTMLScriptRunner::create(&document, this)) | 110 , m_scriptRunner(HTMLScriptRunner::create(&document, this)) |
111 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, parserContentPolicy
(), reportErrors, m_options)) | 111 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, parserContentPolicy
(), reportErrors, m_options)) |
112 , m_parserScheduler(HTMLParserScheduler::create(this)) | 112 , m_parserScheduler(HTMLParserScheduler::create(this)) |
113 , m_xssAuditorDelegate(&document) | 113 , m_xssAuditorDelegate(&document) |
114 , m_weakFactory(this) | 114 , m_weakFactory(this) |
115 , m_preloader(HTMLResourcePreloader::create(document)) | 115 , m_preloader(HTMLResourcePreloader::create(document)) |
116 , m_isPinnedToMainThread(false) | 116 , m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing) |
117 , m_endWasDelayed(false) | 117 , m_endWasDelayed(false) |
118 , m_haveBackgroundParser(false) | 118 , m_haveBackgroundParser(false) |
119 , m_tasksWereSuspended(false) | 119 , m_tasksWereSuspended(false) |
120 , m_pumpSessionNestingLevel(0) | 120 , m_pumpSessionNestingLevel(0) |
121 , m_pumpSpeculationsSessionNestingLevel(0) | 121 , m_pumpSpeculationsSessionNestingLevel(0) |
122 { | 122 { |
123 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); | 123 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); |
124 } | 124 } |
125 | 125 |
126 // FIXME: Member variables should be grouped into self-initializing structs to | 126 // FIXME: Member variables should be grouped into self-initializing structs to |
127 // minimize code duplication between these constructors. | 127 // minimize code duplication between these constructors. |
128 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
extElement, ParserContentPolicy parserContentPolicy) | 128 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
extElement, ParserContentPolicy parserContentPolicy) |
129 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) | 129 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) |
130 , m_options(&fragment->document()) | 130 , m_options(&fragment->document()) |
131 , m_token(adoptPtr(new HTMLToken)) | 131 , m_token(adoptPtr(new HTMLToken)) |
132 , m_tokenizer(HTMLTokenizer::create(m_options)) | 132 , m_tokenizer(HTMLTokenizer::create(m_options)) |
133 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this
->parserContentPolicy(), m_options)) | 133 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this
->parserContentPolicy(), m_options)) |
134 , m_xssAuditorDelegate(&fragment->document()) | 134 , m_xssAuditorDelegate(&fragment->document()) |
135 , m_weakFactory(this) | 135 , m_weakFactory(this) |
136 , m_isPinnedToMainThread(true) | 136 , m_shouldUseThreading(false) |
137 , m_endWasDelayed(false) | 137 , m_endWasDelayed(false) |
138 , m_haveBackgroundParser(false) | 138 , m_haveBackgroundParser(false) |
139 , m_tasksWereSuspended(false) | 139 , m_tasksWereSuspended(false) |
140 , m_pumpSessionNestingLevel(0) | 140 , m_pumpSessionNestingLevel(0) |
141 , m_pumpSpeculationsSessionNestingLevel(0) | 141 , m_pumpSpeculationsSessionNestingLevel(0) |
142 { | 142 { |
143 ASSERT(!shouldUseThreading()); | |
144 bool reportErrors = false; // For now document fragment parsing never report
s errors. | 143 bool reportErrors = false; // For now document fragment parsing never report
s errors. |
145 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report
Errors, m_options)); | 144 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report
Errors, m_options)); |
146 m_xssAuditor.initForFragment(); | 145 m_xssAuditor.initForFragment(); |
147 } | 146 } |
148 | 147 |
149 HTMLDocumentParser::~HTMLDocumentParser() | 148 HTMLDocumentParser::~HTMLDocumentParser() |
150 { | 149 { |
151 #if ENABLE(OILPAN) | 150 #if ENABLE(OILPAN) |
152 if (m_haveBackgroundParser) | 151 if (m_haveBackgroundParser) |
153 stopBackgroundParser(); | 152 stopBackgroundParser(); |
(...skipping 14 matching lines...) Expand all Loading... |
168 void HTMLDocumentParser::trace(Visitor* visitor) | 167 void HTMLDocumentParser::trace(Visitor* visitor) |
169 { | 168 { |
170 visitor->trace(m_treeBuilder); | 169 visitor->trace(m_treeBuilder); |
171 visitor->trace(m_xssAuditorDelegate); | 170 visitor->trace(m_xssAuditorDelegate); |
172 visitor->trace(m_scriptRunner); | 171 visitor->trace(m_scriptRunner); |
173 visitor->trace(m_preloader); | 172 visitor->trace(m_preloader); |
174 ScriptableDocumentParser::trace(visitor); | 173 ScriptableDocumentParser::trace(visitor); |
175 HTMLScriptRunnerHost::trace(visitor); | 174 HTMLScriptRunnerHost::trace(visitor); |
176 } | 175 } |
177 | 176 |
178 void HTMLDocumentParser::pinToMainThread() | |
179 { | |
180 ASSERT(!m_haveBackgroundParser); | |
181 ASSERT(!m_isPinnedToMainThread); | |
182 m_isPinnedToMainThread = true; | |
183 if (!m_tokenizer) { | |
184 ASSERT(!m_token); | |
185 m_token = adoptPtr(new HTMLToken); | |
186 m_tokenizer = HTMLTokenizer::create(m_options); | |
187 } | |
188 } | |
189 | |
190 void HTMLDocumentParser::detach() | 177 void HTMLDocumentParser::detach() |
191 { | 178 { |
192 if (m_haveBackgroundParser) | 179 if (m_haveBackgroundParser) |
193 stopBackgroundParser(); | 180 stopBackgroundParser(); |
194 DocumentParser::detach(); | 181 DocumentParser::detach(); |
195 if (m_scriptRunner) | 182 if (m_scriptRunner) |
196 m_scriptRunner->detach(); | 183 m_scriptRunner->detach(); |
197 m_treeBuilder->detach(); | 184 m_treeBuilder->detach(); |
198 // FIXME: It seems wrong that we would have a preload scanner here. | 185 // FIXME: It seems wrong that we would have a preload scanner here. |
199 // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do. | 186 // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 } | 257 } |
271 | 258 |
272 bool HTMLDocumentParser::isScheduledForResume() const | 259 bool HTMLDocumentParser::isScheduledForResume() const |
273 { | 260 { |
274 return m_parserScheduler && m_parserScheduler->isScheduledForResume(); | 261 return m_parserScheduler && m_parserScheduler->isScheduledForResume(); |
275 } | 262 } |
276 | 263 |
277 // Used by HTMLParserScheduler | 264 // Used by HTMLParserScheduler |
278 void HTMLDocumentParser::resumeParsingAfterYield() | 265 void HTMLDocumentParser::resumeParsingAfterYield() |
279 { | 266 { |
280 ASSERT(!m_isPinnedToMainThread); | 267 ASSERT(shouldUseThreading()); |
281 ASSERT(m_haveBackgroundParser); | 268 ASSERT(m_haveBackgroundParser); |
282 | 269 |
283 // pumpPendingSpeculations can cause this parser to be detached from the Doc
ument, | 270 // pumpPendingSpeculations can cause this parser to be detached from the Doc
ument, |
284 // but we need to ensure it isn't deleted yet. | 271 // but we need to ensure it isn't deleted yet. |
285 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); | 272 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); |
286 pumpPendingSpeculations(); | 273 pumpPendingSpeculations(); |
287 } | 274 } |
288 | 275 |
289 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() | 276 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() |
290 { | 277 { |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 | 772 |
786 m_input.appendToEnd(source); | 773 m_input.appendToEnd(source); |
787 | 774 |
788 if (inPumpSession()) { | 775 if (inPumpSession()) { |
789 // We've gotten data off the network in a nested write. | 776 // We've gotten data off the network in a nested write. |
790 // We don't want to consume any more of the input stream now. Do | 777 // We don't want to consume any more of the input stream now. Do |
791 // not worry. We'll consume this data in a less-nested write(). | 778 // not worry. We'll consume this data in a less-nested write(). |
792 return; | 779 return; |
793 } | 780 } |
794 | 781 |
795 // A couple pinToMainThread() callers require synchronous parsing, but can't | |
796 // easily use the insert() method, so we hack append() for them to be synchr
onous. | |
797 // javascript: url handling is one such caller. | |
798 // FIXME: This is gross, and we should separate the concept of synchronous p
arsing | |
799 // from insert() so that only document.write() uses insert. | |
800 ASSERT(m_isPinnedToMainThread); | |
801 pumpTokenizerIfPossible(); | 782 pumpTokenizerIfPossible(); |
802 | 783 |
803 endIfDelayed(); | 784 endIfDelayed(); |
804 } | 785 } |
805 | 786 |
806 void HTMLDocumentParser::end() | 787 void HTMLDocumentParser::end() |
807 { | 788 { |
808 ASSERT(!isDetached()); | 789 ASSERT(!isDetached()); |
809 ASSERT(!isScheduledForResume()); | 790 ASSERT(!isScheduledForResume()); |
810 | 791 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 // but we need to ensure it isn't deleted yet. | 977 // but we need to ensure it isn't deleted yet. |
997 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); | 978 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); |
998 m_scriptRunner->executeScriptsWaitingForResources(); | 979 m_scriptRunner->executeScriptsWaitingForResources(); |
999 if (!isWaitingForScripts()) | 980 if (!isWaitingForScripts()) |
1000 resumeParsingAfterScriptExecution(); | 981 resumeParsingAfterScriptExecution(); |
1001 } | 982 } |
1002 | 983 |
1003 void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFra
gment* fragment, Element* contextElement, ParserContentPolicy parserContentPolic
y) | 984 void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFra
gment* fragment, Element* contextElement, ParserContentPolicy parserContentPolic
y) |
1004 { | 985 { |
1005 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f
ragment, contextElement, parserContentPolicy); | 986 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f
ragment, contextElement, parserContentPolicy); |
1006 parser->insert(source); // Use insert() so that the parser will not yield. | 987 parser->append(source.impl()); |
1007 parser->finish(); | 988 parser->finish(); |
1008 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/
3963151> | 989 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/
3963151> |
1009 parser->detach(); // Allows ~DocumentParser to assert it was detached before
destruction. | 990 parser->detach(); // Allows ~DocumentParser to assert it was detached before
destruction. |
1010 } | 991 } |
1011 | 992 |
1012 void HTMLDocumentParser::suspendScheduledTasks() | 993 void HTMLDocumentParser::suspendScheduledTasks() |
1013 { | 994 { |
1014 ASSERT(!m_tasksWereSuspended); | 995 ASSERT(!m_tasksWereSuspended); |
1015 m_tasksWereSuspended = true; | 996 m_tasksWereSuspended = true; |
1016 if (m_parserScheduler) | 997 if (m_parserScheduler) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) | 1041 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) |
1061 { | 1042 { |
1062 ASSERT(decoder); | 1043 ASSERT(decoder); |
1063 DecodedDataDocumentParser::setDecoder(decoder); | 1044 DecodedDataDocumentParser::setDecoder(decoder); |
1064 | 1045 |
1065 if (m_haveBackgroundParser) | 1046 if (m_haveBackgroundParser) |
1066 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco
der, m_backgroundParser, takeDecoder())); | 1047 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco
der, m_backgroundParser, takeDecoder())); |
1067 } | 1048 } |
1068 | 1049 |
1069 } | 1050 } |
OLD | NEW |