Chromium Code Reviews| 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 15 matching lines...) Expand all Loading... | |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/html/parser/HTMLDocumentParser.h" | 27 #include "core/html/parser/HTMLDocumentParser.h" |
| 28 | 28 |
| 29 #include "HTMLNames.h" | 29 #include "HTMLNames.h" |
| 30 #include "core/dom/DocumentFragment.h" | 30 #include "core/dom/DocumentFragment.h" |
| 31 #include "core/dom/Element.h" | 31 #include "core/dom/Element.h" |
| 32 #include "core/html/HTMLDocument.h" | 32 #include "core/html/HTMLDocument.h" |
| 33 #include "core/html/parser/AtomicHTMLToken.h" | 33 #include "core/html/parser/AtomicHTMLToken.h" |
| 34 #include "core/html/parser/BackgroundHTMLParser.h" | 34 #include "core/html/parser/BackgroundHTMLParser.h" |
| 35 #include "core/html/parser/HTMLParserScheduler.h" | 35 #include "core/html/parser/HTMLParserScheduler.h" |
| 36 #include "core/html/parser/HTMLParserThread.h" | |
| 37 #include "core/html/parser/HTMLScriptRunner.h" | 36 #include "core/html/parser/HTMLScriptRunner.h" |
| 38 #include "core/html/parser/HTMLTreeBuilder.h" | 37 #include "core/html/parser/HTMLTreeBuilder.h" |
| 39 #include "core/inspector/InspectorInstrumentation.h" | 38 #include "core/inspector/InspectorInstrumentation.h" |
| 40 #include "core/frame/Frame.h" | 39 #include "core/frame/Frame.h" |
| 40 #include "core/loader/DocumentLoader.h" | |
| 41 #include "platform/SharedBuffer.h" | 41 #include "platform/SharedBuffer.h" |
| 42 #include "platform/Task.h" | |
| 42 #include "platform/TraceEvent.h" | 43 #include "platform/TraceEvent.h" |
| 44 #include "public/platform/WebParserResourceBridge.h" | |
| 45 #include "public/platform/WebThread.h" | |
| 43 #include "wtf/Functional.h" | 46 #include "wtf/Functional.h" |
| 44 | 47 |
| 45 namespace WebCore { | 48 namespace WebCore { |
| 46 | 49 |
| 47 using namespace HTMLNames; | 50 using namespace HTMLNames; |
| 48 | 51 |
| 49 // This is a direct transcription of step 4 from: | 52 // This is a direct transcription of step 4 from: |
| 50 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag ment-case | 53 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag ment-case |
| 51 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem ent, bool reportErrors, const HTMLParserOptions& options) | 54 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem ent, bool reportErrors, const HTMLParserOptions& options) |
| 52 { | 55 { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 67 if (contextTag.matches(scriptTag)) | 70 if (contextTag.matches(scriptTag)) |
| 68 return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PL AINTEXTState; | 71 return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PL AINTEXTState; |
| 69 if (contextTag.matches(plaintextTag)) | 72 if (contextTag.matches(plaintextTag)) |
| 70 return HTMLTokenizer::PLAINTEXTState; | 73 return HTMLTokenizer::PLAINTEXTState; |
| 71 return HTMLTokenizer::DataState; | 74 return HTMLTokenizer::DataState; |
| 72 } | 75 } |
| 73 | 76 |
| 74 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors ) | 77 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors ) |
| 75 : ScriptableDocumentParser(document) | 78 : ScriptableDocumentParser(document) |
| 76 , m_options(document) | 79 , m_options(document) |
| 77 , m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken)) | |
| 78 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_opt ions)) | |
| 79 , m_scriptRunner(HTMLScriptRunner::create(document, this)) | 80 , m_scriptRunner(HTMLScriptRunner::create(document, this)) |
| 80 , m_treeBuilder(HTMLTreeBuilder::create(this, document, parserContentPolicy( ), reportErrors, m_options)) | 81 , m_treeBuilder(HTMLTreeBuilder::create(this, document, parserContentPolicy( ), reportErrors, m_options)) |
| 81 , m_parserScheduler(HTMLParserScheduler::create(this)) | 82 , m_parserScheduler(HTMLParserScheduler::create(this)) |
| 82 , m_xssAuditorDelegate(document) | 83 , m_xssAuditorDelegate(document) |
| 83 , m_weakFactory(this) | 84 , m_weakFactory(this) |
| 84 , m_preloader(adoptPtr(new HTMLResourcePreloader(document))) | 85 , m_preloader(adoptPtr(new HTMLResourcePreloader(document))) |
| 85 , m_isPinnedToMainThread(false) | 86 , m_isPinnedToMainThread(false) |
| 86 , m_endWasDelayed(false) | 87 , m_endWasDelayed(false) |
| 87 , m_haveBackgroundParser(false) | |
| 88 , m_pumpSessionNestingLevel(0) | 88 , m_pumpSessionNestingLevel(0) |
| 89 , m_parserThread(0) | |
| 90 , m_parserThreadIsStandalone(false) | |
| 89 { | 91 { |
| 90 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); | 92 if (shouldUseThreading()) |
| 93 startBackgroundParser(); | |
|
abarth-chromium
2013/12/18 18:28:49
Does this integrate correctly with m_isPinnedToMai
oystein (OOO til 10th of July)
2014/01/13 23:19:50
As far as I can tell so far, parsers which aren't
| |
| 94 | |
| 95 if (!m_parserThread) { | |
| 96 m_token = adoptPtr(new HTMLToken); | |
| 97 m_tokenizer = HTMLTokenizer::create(m_options); | |
| 98 } | |
| 91 } | 99 } |
| 92 | 100 |
| 93 // FIXME: Member variables should be grouped into self-initializing structs to | 101 // FIXME: Member variables should be grouped into self-initializing structs to |
| 94 // minimize code duplication between these constructors. | 102 // minimize code duplication between these constructors. |
| 95 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont extElement, ParserContentPolicy parserContentPolicy) | 103 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont extElement, ParserContentPolicy parserContentPolicy) |
| 96 : ScriptableDocumentParser(&fragment->document(), parserContentPolicy) | 104 : ScriptableDocumentParser(&fragment->document(), parserContentPolicy) |
| 97 , m_options(&fragment->document()) | 105 , m_options(&fragment->document()) |
| 98 , m_token(adoptPtr(new HTMLToken)) | 106 , m_token(adoptPtr(new HTMLToken)) |
| 99 , m_tokenizer(HTMLTokenizer::create(m_options)) | 107 , m_tokenizer(HTMLTokenizer::create(m_options)) |
| 100 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this ->parserContentPolicy(), m_options)) | 108 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this ->parserContentPolicy(), m_options)) |
| 101 , m_xssAuditorDelegate(&fragment->document()) | 109 , m_xssAuditorDelegate(&fragment->document()) |
| 102 , m_weakFactory(this) | 110 , m_weakFactory(this) |
| 103 , m_isPinnedToMainThread(true) | 111 , m_isPinnedToMainThread(true) |
| 104 , m_endWasDelayed(false) | 112 , m_endWasDelayed(false) |
| 105 , m_haveBackgroundParser(false) | |
| 106 , m_pumpSessionNestingLevel(0) | 113 , m_pumpSessionNestingLevel(0) |
| 114 , m_parserThread(0) | |
| 115 , m_parserThreadIsStandalone(false) | |
| 107 { | 116 { |
| 108 ASSERT(!shouldUseThreading()); | 117 ASSERT(!shouldUseThreading()); |
| 109 bool reportErrors = false; // For now document fragment parsing never report s errors. | 118 bool reportErrors = false; // For now document fragment parsing never report s errors. |
| 110 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report Errors, m_options)); | 119 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report Errors, m_options)); |
| 111 m_xssAuditor.initForFragment(); | 120 m_xssAuditor.initForFragment(); |
| 112 } | 121 } |
| 113 | 122 |
| 114 HTMLDocumentParser::~HTMLDocumentParser() | 123 HTMLDocumentParser::~HTMLDocumentParser() |
| 115 { | 124 { |
| 116 ASSERT(!m_parserScheduler); | 125 ASSERT(!m_parserScheduler); |
| 117 ASSERT(!m_pumpSessionNestingLevel); | 126 ASSERT(!m_pumpSessionNestingLevel); |
| 118 ASSERT(!m_preloadScanner); | 127 ASSERT(!m_preloadScanner); |
| 119 ASSERT(!m_insertionPreloadScanner); | 128 ASSERT(!m_insertionPreloadScanner); |
| 120 ASSERT(!m_haveBackgroundParser); | 129 ASSERT(!m_parserThread); |
| 121 // FIXME: We should be able to ASSERT(m_speculations.isEmpty()), | 130 // FIXME: We should be able to ASSERT(m_speculations.isEmpty()), |
| 122 // but there are cases where that's not true currently. For example, | 131 // but there are cases where that's not true currently. For example, |
| 123 // we we're told to stop parsing before we've consumed all the input. | 132 // we we're told to stop parsing before we've consumed all the input. |
| 124 } | 133 } |
| 125 | 134 |
| 126 void HTMLDocumentParser::pinToMainThread() | 135 void HTMLDocumentParser::pinToMainThread() |
| 127 { | 136 { |
| 128 ASSERT(!m_haveBackgroundParser); | 137 ASSERT(!m_parserThread); |
| 129 ASSERT(!m_isPinnedToMainThread); | 138 ASSERT(!m_isPinnedToMainThread); |
| 130 m_isPinnedToMainThread = true; | 139 m_isPinnedToMainThread = true; |
| 131 if (!m_tokenizer) { | 140 if (!m_tokenizer) { |
| 132 ASSERT(!m_token); | 141 ASSERT(!m_token); |
| 133 m_token = adoptPtr(new HTMLToken); | 142 m_token = adoptPtr(new HTMLToken); |
| 134 m_tokenizer = HTMLTokenizer::create(m_options); | 143 m_tokenizer = HTMLTokenizer::create(m_options); |
| 135 } | 144 } |
| 136 } | 145 } |
| 137 | 146 |
| 138 void HTMLDocumentParser::detach() | 147 void HTMLDocumentParser::detach() |
| 139 { | 148 { |
| 140 if (m_haveBackgroundParser) | 149 if (m_parserThread) |
| 141 stopBackgroundParser(); | 150 stopBackgroundParser(); |
| 142 DocumentParser::detach(); | 151 DocumentParser::detach(); |
| 143 if (m_scriptRunner) | 152 if (m_scriptRunner) |
| 144 m_scriptRunner->detach(); | 153 m_scriptRunner->detach(); |
| 145 m_treeBuilder->detach(); | 154 m_treeBuilder->detach(); |
| 146 // FIXME: It seems wrong that we would have a preload scanner here. | 155 // FIXME: It seems wrong that we would have a preload scanner here. |
| 147 // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do. | 156 // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do. |
| 148 m_preloadScanner.clear(); | 157 m_preloadScanner.clear(); |
| 149 m_insertionPreloadScanner.clear(); | 158 m_insertionPreloadScanner.clear(); |
| 150 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers. | 159 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers. |
| 151 } | 160 } |
| 152 | 161 |
| 153 void HTMLDocumentParser::stopParsing() | 162 void HTMLDocumentParser::stopParsing() |
| 154 { | 163 { |
| 155 DocumentParser::stopParsing(); | 164 DocumentParser::stopParsing(); |
| 156 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers. | 165 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers. |
| 157 if (m_haveBackgroundParser) | 166 if (m_parserThread) |
| 158 stopBackgroundParser(); | 167 stopBackgroundParser(); |
| 159 } | 168 } |
| 160 | 169 |
| 161 // This kicks off "Once the user agent stops parsing" as described by: | 170 // This kicks off "Once the user agent stops parsing" as described by: |
| 162 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the- end | 171 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the- end |
| 163 void HTMLDocumentParser::prepareToStopParsing() | 172 void HTMLDocumentParser::prepareToStopParsing() |
| 164 { | 173 { |
| 165 // FIXME: It may not be correct to disable this for the background parser. | 174 // FIXME: It may not be correct to disable this for the background parser. |
| 166 // That means hasInsertionPoint() may not be correct in some cases. | 175 // That means hasInsertionPoint() may not be correct in some cases. |
| 167 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); | 176 ASSERT(!hasInsertionPoint() || m_parserThread); |
| 168 | 177 |
| 169 // pumpTokenizer can cause this parser to be detached from the Document, | 178 // pumpTokenizer can cause this parser to be detached from the Document, |
| 170 // but we need to ensure it isn't deleted yet. | 179 // but we need to ensure it isn't deleted yet. |
| 171 RefPtr<HTMLDocumentParser> protect(this); | 180 RefPtr<HTMLDocumentParser> protect(this); |
| 172 | 181 |
| 173 // NOTE: This pump should only ever emit buffered character tokens, | 182 // NOTE: This pump should only ever emit buffered character tokens, |
| 174 // so ForceSynchronous vs. AllowYield should be meaningless. | 183 // so ForceSynchronous vs. AllowYield should be meaningless. |
| 175 if (m_tokenizer) { | 184 if (m_tokenizer) { |
| 176 ASSERT(!m_haveBackgroundParser); | 185 ASSERT(!m_parserThread); |
| 177 pumpTokenizerIfPossible(ForceSynchronous); | 186 pumpTokenizerIfPossible(ForceSynchronous); |
| 178 } | 187 } |
| 179 | 188 |
| 180 if (isStopped()) | 189 if (isStopped()) |
| 181 return; | 190 return; |
| 182 | 191 |
| 183 DocumentParser::prepareToStopParsing(); | 192 DocumentParser::prepareToStopParsing(); |
| 184 | 193 |
| 185 // We will not have a scriptRunner when parsing a DocumentFragment. | 194 // We will not have a scriptRunner when parsing a DocumentFragment. |
| 186 if (m_scriptRunner) | 195 if (m_scriptRunner) |
| 187 document()->setReadyState(Document::Interactive); | 196 document()->setReadyState(Document::Interactive); |
| 188 | 197 |
| 189 // Setting the ready state above can fire mutation event and detach us | 198 // Setting the ready state above can fire mutation event and detach us |
| 190 // from underneath. In that case, just bail out. | 199 // from underneath. In that case, just bail out. |
| 191 if (isDetached()) | 200 if (isDetached()) |
| 192 return; | 201 return; |
| 193 | 202 |
| 194 attemptToRunDeferredScriptsAndEnd(); | 203 attemptToRunDeferredScriptsAndEnd(); |
| 195 } | 204 } |
| 196 | 205 |
| 197 bool HTMLDocumentParser::isParsingFragment() const | 206 bool HTMLDocumentParser::isParsingFragment() const |
| 198 { | 207 { |
| 199 return m_treeBuilder->isParsingFragment(); | 208 return m_treeBuilder->isParsingFragment(); |
| 200 } | 209 } |
| 201 | 210 |
| 202 bool HTMLDocumentParser::processingData() const | 211 bool HTMLDocumentParser::processingData() const |
| 203 { | 212 { |
| 204 return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser; | 213 return isScheduledForResume() || inPumpSession() || m_parserThread; |
| 205 } | 214 } |
| 206 | 215 |
| 207 void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode) | 216 void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode) |
| 208 { | 217 { |
| 209 if (isStopped()) | 218 if (isStopped()) |
| 210 return; | 219 return; |
| 211 if (isWaitingForScripts()) | 220 if (isWaitingForScripts()) |
| 212 return; | 221 return; |
| 213 | 222 |
| 214 // Once a resume is scheduled, HTMLParserScheduler controls when we next pum p. | 223 // Once a resume is scheduled, HTMLParserScheduler controls when we next pum p. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 226 } | 235 } |
| 227 | 236 |
| 228 // Used by HTMLParserScheduler | 237 // Used by HTMLParserScheduler |
| 229 void HTMLDocumentParser::resumeParsingAfterYield() | 238 void HTMLDocumentParser::resumeParsingAfterYield() |
| 230 { | 239 { |
| 231 ASSERT(!m_isPinnedToMainThread); | 240 ASSERT(!m_isPinnedToMainThread); |
| 232 // pumpTokenizer can cause this parser to be detached from the Document, | 241 // pumpTokenizer can cause this parser to be detached from the Document, |
| 233 // but we need to ensure it isn't deleted yet. | 242 // but we need to ensure it isn't deleted yet. |
| 234 RefPtr<HTMLDocumentParser> protect(this); | 243 RefPtr<HTMLDocumentParser> protect(this); |
| 235 | 244 |
| 236 if (m_haveBackgroundParser) { | 245 if (m_parserThread) { |
| 237 pumpPendingSpeculations(); | 246 pumpPendingSpeculations(); |
| 238 return; | 247 return; |
| 239 } | 248 } |
| 240 | 249 |
| 241 // We should never be here unless we can pump immediately. Call pumpTokeniz er() | 250 // We should never be here unless we can pump immediately. Call pumpTokeniz er() |
| 242 // directly so that ASSERTS will fire if we're wrong. | 251 // directly so that ASSERTS will fire if we're wrong. |
| 243 pumpTokenizer(AllowYield); | 252 pumpTokenizer(AllowYield); |
| 244 endIfDelayed(); | 253 endIfDelayed(); |
| 245 } | 254 } |
| 246 | 255 |
| 247 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() | 256 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() |
| 248 { | 257 { |
| 249 ASSERT(scriptingContentIsAllowed(parserContentPolicy())); | 258 ASSERT(scriptingContentIsAllowed(parserContentPolicy())); |
| 250 | 259 |
| 251 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); | 260 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); |
| 252 RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptSta rtPosition); | 261 RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptSta rtPosition); |
| 253 // We will not have a scriptRunner when parsing a DocumentFragment. | 262 // We will not have a scriptRunner when parsing a DocumentFragment. |
| 254 if (m_scriptRunner) | 263 if (m_scriptRunner) |
| 255 m_scriptRunner->execute(scriptElement.release(), scriptStartPosition); | 264 m_scriptRunner->execute(scriptElement.release(), scriptStartPosition); |
| 256 } | 265 } |
| 257 | 266 |
| 258 bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses sion) | 267 bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses sion) |
| 259 { | 268 { |
| 260 if (isStopped()) | 269 if (isStopped()) |
| 261 return false; | 270 return false; |
| 262 | 271 |
| 263 ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous); | 272 ASSERT(!m_parserThread || mode == ForceSynchronous); |
| 264 | 273 |
| 265 if (isWaitingForScripts()) { | 274 if (isWaitingForScripts()) { |
| 266 if (mode == AllowYield) | 275 if (mode == AllowYield) |
| 267 m_parserScheduler->checkForYieldBeforeScript(session); | 276 m_parserScheduler->checkForYieldBeforeScript(session); |
| 268 | 277 |
| 269 // If we don't run the script, we cannot allow the next token to be take n. | 278 // If we don't run the script, we cannot allow the next token to be take n. |
| 270 if (session.needsYield) | 279 if (session.needsYield) |
| 271 return false; | 280 return false; |
| 272 | 281 |
| 273 // If we're paused waiting for a script, we try to execute scripts befor e continuing. | 282 // If we're paused waiting for a script, we try to execute scripts befor e continuing. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately. | 324 chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately. |
| 316 m_speculations.append(chunk); | 325 m_speculations.append(chunk); |
| 317 pumpPendingSpeculations(); | 326 pumpPendingSpeculations(); |
| 318 } | 327 } |
| 319 | 328 |
| 320 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume ntEncodingData& data) | 329 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume ntEncodingData& data) |
| 321 { | 330 { |
| 322 document()->setEncodingData(data); | 331 document()->setEncodingData(data); |
| 323 } | 332 } |
| 324 | 333 |
| 334 void HTMLDocumentParser::destructResourceBridge(PassOwnPtr<blink::WebParserResou rceBridge> resourceBridge) | |
| 335 { | |
| 336 // Here to let the resource bridge be destructed on the main thread. | |
| 337 } | |
| 338 | |
| 325 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk) | 339 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk) |
| 326 { | 340 { |
| 327 ASSERT(chunk); | 341 ASSERT(chunk); |
| 328 if (isWaitingForScripts()) { | 342 if (isWaitingForScripts()) { |
| 329 // We're waiting on a network script, just save the chunk, we'll get | 343 // We're waiting on a network script, just save the chunk, we'll get |
| 330 // a second validateSpeculations call after the script completes. | 344 // a second validateSpeculations call after the script completes. |
| 331 // This call should have been made immediately after runScriptsForPaused TreeBuilder | 345 // This call should have been made immediately after runScriptsForPaused TreeBuilder |
| 332 // which may have started a network load and left us waiting. | 346 // which may have started a network load and left us waiting. |
| 333 ASSERT(!m_lastChunkBeforeScript); | 347 ASSERT(!m_lastChunkBeforeScript); |
| 334 m_lastChunkBeforeScript = chunk; | 348 m_lastChunkBeforeScript = chunk; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 checkpoint->parser = m_weakFactory.createWeakPtr(); | 384 checkpoint->parser = m_weakFactory.createWeakPtr(); |
| 371 checkpoint->token = token; | 385 checkpoint->token = token; |
| 372 checkpoint->tokenizer = tokenizer; | 386 checkpoint->tokenizer = tokenizer; |
| 373 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil der.get()); | 387 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil der.get()); |
| 374 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; | 388 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; |
| 375 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner Checkpoint; | 389 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner Checkpoint; |
| 376 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); | 390 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); |
| 377 m_input.current().clear(); // FIXME: This should be passed in instead of cle ared. | 391 m_input.current().clear(); // FIXME: This should be passed in instead of cle ared. |
| 378 | 392 |
| 379 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); | 393 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); |
| 380 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::resumeFrom, m_backgroundParser, checkpoint.release())); | 394 ASSERT(m_parserThread); |
| 395 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::resumeFrom, m_ backgroundParser, checkpoint.release()))); | |
| 381 } | 396 } |
| 382 | 397 |
| 383 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse dChunk> popChunk) | 398 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse dChunk> popChunk) |
| 384 { | 399 { |
| 385 TRACE_EVENT0("webkit", "HTMLDocumentParser::processParsedChunkFromBackground Parser"); | 400 TRACE_EVENT0("webkit", "HTMLDocumentParser::processParsedChunkFromBackground Parser"); |
| 386 | 401 |
| 387 ASSERT_WITH_SECURITY_IMPLICATION(!document()->activeParserCount()); | 402 ASSERT_WITH_SECURITY_IMPLICATION(!document()->activeParserCount()); |
| 388 ASSERT(!isParsingFragment()); | 403 ASSERT(!isParsingFragment()); |
| 389 ASSERT(!isWaitingForScripts()); | 404 ASSERT(!isWaitingForScripts()); |
| 390 ASSERT(!isStopped()); | 405 ASSERT(!isStopped()); |
| 391 // ASSERT that this object is both attached to the Document and protected. | 406 // ASSERT that this object is both attached to the Document and protected. |
| 392 ASSERT(refCount() >= 2); | 407 ASSERT(refCount() >= 2); |
| 393 ASSERT(shouldUseThreading()); | 408 ASSERT(shouldUseThreading()); |
| 394 ASSERT(!m_tokenizer); | 409 ASSERT(!m_tokenizer); |
| 395 ASSERT(!m_token); | 410 ASSERT(!m_token); |
| 396 ASSERT(!m_lastChunkBeforeScript); | 411 ASSERT(!m_lastChunkBeforeScript); |
| 412 ASSERT(m_parserThread); | |
| 397 | 413 |
| 398 ActiveParserSession session(contextForParsingSession()); | 414 ActiveParserSession session(contextForParsingSession()); |
| 399 | 415 |
| 400 OwnPtr<ParsedChunk> chunk(popChunk); | 416 OwnPtr<ParsedChunk> chunk(popChunk); |
| 401 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release(); | 417 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release(); |
| 402 | 418 |
| 403 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::startedChun kWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); | 419 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::startedChunkWi thCheckpoint, m_backgroundParser, chunk->inputCheckpoint))); |
| 404 | 420 |
| 405 for (XSSInfoStream::const_iterator it = chunk->xssInfos.begin(); it != chunk ->xssInfos.end(); ++it) { | 421 for (XSSInfoStream::const_iterator it = chunk->xssInfos.begin(); it != chunk ->xssInfos.end(); ++it) { |
| 406 m_textPosition = (*it)->m_textPosition; | 422 m_textPosition = (*it)->m_textPosition; |
| 407 m_xssAuditorDelegate.didBlockScript(**it); | 423 m_xssAuditorDelegate.didBlockScript(**it); |
| 408 if (isStopped()) | 424 if (isStopped()) |
| 409 break; | 425 break; |
| 410 } | 426 } |
| 411 | 427 |
| 412 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != to kens->end(); ++it) { | 428 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != to kens->end(); ++it) { |
| 413 ASSERT(!isWaitingForScripts()); | 429 ASSERT(!isWaitingForScripts()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 m_parserScheduler->scheduleForResume(); | 500 m_parserScheduler->scheduleForResume(); |
| 485 break; | 501 break; |
| 486 } | 502 } |
| 487 } | 503 } |
| 488 | 504 |
| 489 InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt()); | 505 InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt()); |
| 490 } | 506 } |
| 491 | 507 |
| 492 void HTMLDocumentParser::forcePlaintextForTextDocument() | 508 void HTMLDocumentParser::forcePlaintextForTextDocument() |
| 493 { | 509 { |
| 494 if (shouldUseThreading()) { | 510 if (m_parserThread) |
| 495 // This method is called before any data is appended, so we have to star t | 511 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::forcePlain textForTextDocument, m_backgroundParser))); |
| 496 // the background parser ourselves. | 512 else |
| 497 if (!m_haveBackgroundParser) | |
| 498 startBackgroundParser(); | |
| 499 | |
| 500 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::forcePl aintextForTextDocument, m_backgroundParser)); | |
| 501 } else | |
| 502 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); | 513 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); |
| 503 } | 514 } |
| 504 | 515 |
| 505 Document* HTMLDocumentParser::contextForParsingSession() | 516 Document* HTMLDocumentParser::contextForParsingSession() |
| 506 { | 517 { |
| 507 // The parsing session should interact with the document only when parsing | 518 // The parsing session should interact with the document only when parsing |
| 508 // non-fragments. Otherwise, we might delay the load event mistakenly. | 519 // non-fragments. Otherwise, we might delay the load event mistakenly. |
| 509 if (isParsingFragment()) | 520 if (isParsingFragment()) |
| 510 return 0; | 521 return 0; |
| 511 return document(); | 522 return document(); |
| 512 } | 523 } |
| 513 | 524 |
| 514 void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) | 525 void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) |
| 515 { | 526 { |
| 516 ASSERT(!isStopped()); | 527 ASSERT(!isStopped()); |
| 517 ASSERT(!isScheduledForResume()); | 528 ASSERT(!isScheduledForResume()); |
| 518 // ASSERT that this object is both attached to the Document and protected. | 529 // ASSERT that this object is both attached to the Document and protected. |
| 519 ASSERT(refCount() >= 2); | 530 ASSERT(refCount() >= 2); |
| 520 ASSERT(m_tokenizer); | 531 ASSERT(m_tokenizer); |
| 521 ASSERT(m_token); | 532 ASSERT(m_token); |
| 522 ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous); | 533 ASSERT(!m_parserThread || mode == ForceSynchronous); |
| 523 | 534 |
| 524 PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession()); | 535 PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession()); |
| 525 | 536 |
| 526 // We tell the InspectorInstrumentation about every pump, even if we | 537 // We tell the InspectorInstrumentation about every pump, even if we |
| 527 // end up pumping nothing. It can filter out empty pumps itself. | 538 // end up pumping nothing. It can filter out empty pumps itself. |
| 528 // FIXME: m_input.current().length() is only accurate if we | 539 // FIXME: m_input.current().length() is only accurate if we |
| 529 // end up parsing the whole buffer in this pump. We should pass how | 540 // end up parsing the whole buffer in this pump. We should pass how |
| 530 // much we parsed as part of didWriteHTML instead of willWriteHTML. | 541 // much we parsed as part of didWriteHTML instead of willWriteHTML. |
| 531 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteH TML(document(), m_input.current().currentLine().zeroBasedInt()); | 542 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteH TML(document(), m_input.current().currentLine().zeroBasedInt()); |
| 532 | 543 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 return; | 638 return; |
| 628 | 639 |
| 629 TRACE_EVENT0("webkit", "HTMLDocumentParser::insert"); | 640 TRACE_EVENT0("webkit", "HTMLDocumentParser::insert"); |
| 630 | 641 |
| 631 // pumpTokenizer can cause this parser to be detached from the Document, | 642 // pumpTokenizer can cause this parser to be detached from the Document, |
| 632 // but we need to ensure it isn't deleted yet. | 643 // but we need to ensure it isn't deleted yet. |
| 633 RefPtr<HTMLDocumentParser> protect(this); | 644 RefPtr<HTMLDocumentParser> protect(this); |
| 634 | 645 |
| 635 if (!m_tokenizer) { | 646 if (!m_tokenizer) { |
| 636 ASSERT(!inPumpSession()); | 647 ASSERT(!inPumpSession()); |
| 637 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); | 648 ASSERT(m_parserThread || wasCreatedByScript()); |
| 638 m_token = adoptPtr(new HTMLToken); | 649 m_token = adoptPtr(new HTMLToken); |
| 639 m_tokenizer = HTMLTokenizer::create(m_options); | 650 m_tokenizer = HTMLTokenizer::create(m_options); |
| 640 } | 651 } |
| 641 | 652 |
| 642 SegmentedString excludedLineNumberSource(source); | 653 SegmentedString excludedLineNumberSource(source); |
| 643 excludedLineNumberSource.setExcludeLineNumbers(); | 654 excludedLineNumberSource.setExcludeLineNumbers(); |
| 644 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); | 655 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); |
| 645 pumpTokenizerIfPossible(ForceSynchronous); | 656 pumpTokenizerIfPossible(ForceSynchronous); |
| 646 | 657 |
| 647 if (isWaitingForScripts()) { | 658 if (isWaitingForScripts()) { |
| 648 // Check the document.write() output with a separate preload scanner as | 659 // Check the document.write() output with a separate preload scanner as |
| 649 // the main scanner can't deal with insertions. | 660 // the main scanner can't deal with insertions. |
| 650 if (!m_insertionPreloadScanner) | 661 if (!m_insertionPreloadScanner) |
| 651 m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_option s, document()->url(), document()->devicePixelRatio())); | 662 m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_option s, document()->url(), document()->devicePixelRatio())); |
| 652 | 663 |
| 653 m_insertionPreloadScanner->appendToEnd(source); | 664 m_insertionPreloadScanner->appendToEnd(source); |
| 654 m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseEleme ntURL()); | 665 m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseEleme ntURL()); |
| 655 } | 666 } |
| 656 | 667 |
| 657 endIfDelayed(); | 668 endIfDelayed(); |
| 658 } | 669 } |
| 659 | 670 |
| 660 void HTMLDocumentParser::startBackgroundParser() | 671 void HTMLDocumentParser::startBackgroundParser() |
| 661 { | 672 { |
| 662 ASSERT(shouldUseThreading()); | 673 ASSERT(shouldUseThreading()); |
| 663 ASSERT(!m_haveBackgroundParser); | 674 ASSERT(!m_parserThread); |
| 664 m_haveBackgroundParser = true; | 675 |
| 676 OwnPtr<blink::WebParserResourceBridge> resourceBridge = document()->loader() ->constructParserResourceBridge(); | |
| 677 if (!resourceBridge) | |
| 678 return; | |
| 679 | |
| 680 m_parserThread = resourceBridge->getParserThread(); | |
|
abarth-chromium
2013/12/18 18:28:49
getParserThread -> parserThread
| |
| 681 ASSERT(m_parserThread); | |
| 665 | 682 |
| 666 RefPtr<WeakReference<BackgroundHTMLParser> > reference = WeakReference<Backg roundHTMLParser>::createUnbound(); | 683 RefPtr<WeakReference<BackgroundHTMLParser> > reference = WeakReference<Backg roundHTMLParser>::createUnbound(); |
| 667 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); | 684 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); |
| 668 | 685 |
| 669 OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new Background HTMLParser::Configuration); | 686 OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new Background HTMLParser::Configuration); |
| 670 config->options = m_options; | 687 config->options = m_options; |
| 671 config->parser = m_weakFactory.createWeakPtr(); | 688 config->parser = m_weakFactory.createWeakPtr(); |
| 672 config->xssAuditor = adoptPtr(new XSSAuditor); | 689 config->xssAuditor = adoptPtr(new XSSAuditor); |
| 673 config->xssAuditor->init(document(), &m_xssAuditorDelegate); | 690 config->xssAuditor->init(document(), &m_xssAuditorDelegate); |
| 674 config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url(). copy(), document()->devicePixelRatio())); | 691 config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url(). copy(), document()->devicePixelRatio())); |
| 675 config->decoder = takeDecoder(); | 692 config->decoder = takeDecoder(); |
| 693 config->resourceBridge = resourceBridge.release(); | |
| 676 | 694 |
| 677 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); | 695 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); |
| 678 ASSERT(config->preloadScanner->isSafeToSendToAnotherThread()); | 696 ASSERT(config->preloadScanner->isSafeToSendToAnotherThread()); |
| 679 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::start, refe rence.release(), config.release())); | 697 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::start, referen ce.release(), config.release()))); |
| 680 } | 698 } |
| 681 | 699 |
| 682 void HTMLDocumentParser::stopBackgroundParser() | 700 void HTMLDocumentParser::stopBackgroundParser() |
| 683 { | 701 { |
| 684 ASSERT(shouldUseThreading()); | 702 ASSERT(shouldUseThreading()); |
| 685 ASSERT(m_haveBackgroundParser); | 703 ASSERT(m_parserThread); |
| 686 m_haveBackgroundParser = false; | |
| 687 | 704 |
| 688 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::stop, m_bac kgroundParser)); | 705 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::stop, m_backgr oundParser))); |
| 706 m_parserThread = 0; | |
| 689 m_weakFactory.revokeAll(); | 707 m_weakFactory.revokeAll(); |
| 690 } | 708 } |
| 691 | 709 |
| 692 void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource) | 710 void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource) |
| 693 { | 711 { |
| 694 if (isStopped()) | 712 if (isStopped()) |
| 695 return; | 713 return; |
| 696 | 714 |
| 697 // We should never reach this point if we're using a parser thread, | 715 // We should never reach this point if we're using a parser thread, |
| 698 // as appendBytes() will directly ship the data to the thread. | 716 // as appendBytes() will directly ship the data to the thread. |
| 699 ASSERT(!shouldUseThreading()); | 717 ASSERT(!m_parserThread); |
| 700 | 718 |
| 701 // pumpTokenizer can cause this parser to be detached from the Document, | 719 // pumpTokenizer can cause this parser to be detached from the Document, |
| 702 // but we need to ensure it isn't deleted yet. | 720 // but we need to ensure it isn't deleted yet. |
| 703 RefPtr<HTMLDocumentParser> protect(this); | 721 RefPtr<HTMLDocumentParser> protect(this); |
| 704 TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->lengt h()); | 722 TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->lengt h()); |
| 705 String source(inputSource); | 723 String source(inputSource); |
| 706 | 724 |
| 707 if (m_preloadScanner) { | 725 if (m_preloadScanner) { |
| 708 if (m_input.current().isEmpty() && !isWaitingForScripts()) { | 726 if (m_input.current().isEmpty() && !isWaitingForScripts()) { |
| 709 // We have parsed until the end of the current input and so are now moving ahead of the preload scanner. | 727 // We have parsed until the end of the current input and so are now moving ahead of the preload scanner. |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 736 pumpTokenizerIfPossible(AllowYield); | 754 pumpTokenizerIfPossible(AllowYield); |
| 737 | 755 |
| 738 endIfDelayed(); | 756 endIfDelayed(); |
| 739 } | 757 } |
| 740 | 758 |
| 741 void HTMLDocumentParser::end() | 759 void HTMLDocumentParser::end() |
| 742 { | 760 { |
| 743 ASSERT(!isDetached()); | 761 ASSERT(!isDetached()); |
| 744 ASSERT(!isScheduledForResume()); | 762 ASSERT(!isScheduledForResume()); |
| 745 | 763 |
| 746 if (m_haveBackgroundParser) | 764 if (m_parserThread) |
| 747 stopBackgroundParser(); | 765 stopBackgroundParser(); |
| 748 | 766 |
| 749 // Informs the the rest of WebCore that parsing is really finished (and dele tes this). | 767 // Informs the the rest of WebCore that parsing is really finished (and dele tes this). |
| 750 m_treeBuilder->finished(); | 768 m_treeBuilder->finished(); |
| 751 } | 769 } |
| 752 | 770 |
| 753 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() | 771 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() |
| 754 { | 772 { |
| 755 ASSERT(isStopping()); | 773 ASSERT(isStopping()); |
| 756 // FIXME: It may not be correct to disable this for the background parser. | 774 // FIXME: It may not be correct to disable this for the background parser. |
| 757 // That means hasInsertionPoint() may not be correct in some cases. | 775 // That means hasInsertionPoint() may not be correct in some cases. |
| 758 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); | 776 ASSERT(!hasInsertionPoint() || m_parserThread); |
| 759 if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing()) | 777 if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing()) |
| 760 return; | 778 return; |
| 761 end(); | 779 end(); |
| 762 } | 780 } |
| 763 | 781 |
| 764 void HTMLDocumentParser::attemptToEnd() | 782 void HTMLDocumentParser::attemptToEnd() |
| 765 { | 783 { |
| 766 // finish() indicates we will not receive any more data. If we are waiting o n | 784 // finish() indicates we will not receive any more data. If we are waiting o n |
| 767 // an external script to load, we can't finish parsing quite yet. | 785 // an external script to load, we can't finish parsing quite yet. |
| 768 | 786 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 788 | 806 |
| 789 void HTMLDocumentParser::finish() | 807 void HTMLDocumentParser::finish() |
| 790 { | 808 { |
| 791 // FIXME: We should ASSERT(!m_parserStopped) here, since it does not | 809 // FIXME: We should ASSERT(!m_parserStopped) here, since it does not |
| 792 // makes sense to call any methods on DocumentParser once it's been stopped. | 810 // makes sense to call any methods on DocumentParser once it's been stopped. |
| 793 // However, FrameLoader::stop calls DocumentParser::finish unconditionally. | 811 // However, FrameLoader::stop calls DocumentParser::finish unconditionally. |
| 794 | 812 |
| 795 // Empty documents never got an append() call, and thus have never started | 813 // Empty documents never got an append() call, and thus have never started |
| 796 // a background parser. In those cases, we ignore shouldUseThreading() | 814 // a background parser. In those cases, we ignore shouldUseThreading() |
| 797 // and fall through to the non-threading case. | 815 // and fall through to the non-threading case. |
| 798 if (m_haveBackgroundParser) { | 816 if (m_parserThread) { |
| 799 if (!m_input.haveSeenEndOfFile()) | 817 if (!m_input.haveSeenEndOfFile()) |
| 800 m_input.closeWithoutMarkingEndOfFile(); | 818 m_input.closeWithoutMarkingEndOfFile(); |
| 801 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::finish, m_backgroundParser)); | 819 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::finish, m_ backgroundParser))); |
| 802 return; | 820 return; |
| 803 } | 821 } |
| 804 | 822 |
| 805 if (!m_tokenizer) { | 823 if (!m_tokenizer) { |
| 806 ASSERT(!m_token); | 824 ASSERT(!m_token); |
| 807 // We're finishing before receiving any data. Rather than booting up | 825 // We're finishing before receiving any data. Rather than booting up |
| 808 // the background parser just to spin it down, we finish parsing | 826 // the background parser just to spin it down, we finish parsing |
| 809 // synchronously. | 827 // synchronously. |
| 810 m_token = adoptPtr(new HTMLToken); | 828 m_token = adoptPtr(new HTMLToken); |
| 811 m_tokenizer = HTMLTokenizer::create(m_options); | 829 m_tokenizer = HTMLTokenizer::create(m_options); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 822 | 840 |
| 823 bool HTMLDocumentParser::isExecutingScript() const | 841 bool HTMLDocumentParser::isExecutingScript() const |
| 824 { | 842 { |
| 825 if (!m_scriptRunner) | 843 if (!m_scriptRunner) |
| 826 return false; | 844 return false; |
| 827 return m_scriptRunner->isExecutingScript(); | 845 return m_scriptRunner->isExecutingScript(); |
| 828 } | 846 } |
| 829 | 847 |
| 830 OrdinalNumber HTMLDocumentParser::lineNumber() const | 848 OrdinalNumber HTMLDocumentParser::lineNumber() const |
| 831 { | 849 { |
| 832 if (m_haveBackgroundParser) | 850 if (m_parserThread) |
| 833 return m_textPosition.m_line; | 851 return m_textPosition.m_line; |
| 834 | 852 |
| 835 return m_input.current().currentLine(); | 853 return m_input.current().currentLine(); |
| 836 } | 854 } |
| 837 | 855 |
| 838 TextPosition HTMLDocumentParser::textPosition() const | 856 TextPosition HTMLDocumentParser::textPosition() const |
| 839 { | 857 { |
| 840 if (m_haveBackgroundParser) | 858 if (m_parserThread) |
| 841 return m_textPosition; | 859 return m_textPosition; |
| 842 | 860 |
| 843 const SegmentedString& currentString = m_input.current(); | 861 const SegmentedString& currentString = m_input.current(); |
| 844 OrdinalNumber line = currentString.currentLine(); | 862 OrdinalNumber line = currentString.currentLine(); |
| 845 OrdinalNumber column = currentString.currentColumn(); | 863 OrdinalNumber column = currentString.currentColumn(); |
| 846 | 864 |
| 847 return TextPosition(line, column); | 865 return TextPosition(line, column); |
| 848 } | 866 } |
| 849 | 867 |
| 850 bool HTMLDocumentParser::isWaitingForScripts() const | 868 bool HTMLDocumentParser::isWaitingForScripts() const |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 861 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); | 879 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); |
| 862 // If either object has a blocking script, the parser should be paused. | 880 // If either object has a blocking script, the parser should be paused. |
| 863 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript; | 881 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript; |
| 864 } | 882 } |
| 865 | 883 |
| 866 void HTMLDocumentParser::resumeParsingAfterScriptExecution() | 884 void HTMLDocumentParser::resumeParsingAfterScriptExecution() |
| 867 { | 885 { |
| 868 ASSERT(!isExecutingScript()); | 886 ASSERT(!isExecutingScript()); |
| 869 ASSERT(!isWaitingForScripts()); | 887 ASSERT(!isWaitingForScripts()); |
| 870 | 888 |
| 871 if (m_haveBackgroundParser) { | 889 if (m_parserThread) { |
| 872 validateSpeculations(m_lastChunkBeforeScript.release()); | 890 validateSpeculations(m_lastChunkBeforeScript.release()); |
| 873 ASSERT(!m_lastChunkBeforeScript); | 891 ASSERT(!m_lastChunkBeforeScript); |
| 874 // processParsedChunkFromBackgroundParser can cause this parser to be de tached from the Document, | 892 // processParsedChunkFromBackgroundParser can cause this parser to be de tached from the Document, |
| 875 // but we need to ensure it isn't deleted yet. | 893 // but we need to ensure it isn't deleted yet. |
| 876 RefPtr<HTMLDocumentParser> protect(this); | 894 RefPtr<HTMLDocumentParser> protect(this); |
| 877 pumpPendingSpeculations(); | 895 pumpPendingSpeculations(); |
| 878 return; | 896 return; |
| 879 } | 897 } |
| 880 | 898 |
| 881 m_insertionPreloadScanner.clear(); | 899 m_insertionPreloadScanner.clear(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 960 { | 978 { |
| 961 if (m_parserScheduler) | 979 if (m_parserScheduler) |
| 962 m_parserScheduler->resume(); | 980 m_parserScheduler->resume(); |
| 963 } | 981 } |
| 964 | 982 |
| 965 void HTMLDocumentParser::appendBytes(const char* data, size_t length) | 983 void HTMLDocumentParser::appendBytes(const char* data, size_t length) |
| 966 { | 984 { |
| 967 if (!length || isDetached()) | 985 if (!length || isDetached()) |
| 968 return; | 986 return; |
| 969 | 987 |
| 970 if (shouldUseThreading()) { | 988 if (m_parserThread) { |
| 971 if (!m_haveBackgroundParser) | 989 if (m_parserThreadIsStandalone) |
| 972 startBackgroundParser(); | 990 return; // If this is set, the parser thread will receive the data d irectly. |
| 973 | 991 |
| 974 OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length)); | 992 OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length)); |
| 975 memcpy(buffer->data(), data, length); | 993 memcpy(buffer->data(), data, length); |
| 976 TRACE_EVENT1("net", "HTMLDocumentParser::appendBytes", "size", (unsigned )length); | 994 TRACE_EVENT1("net", "HTMLDocumentParser::appendBytes", "size", (unsigned )length); |
| 977 | 995 |
| 978 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::appendB ytes, m_backgroundParser, buffer.release())); | 996 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::appendByte s, m_backgroundParser, buffer.release()))); |
| 979 return; | 997 return; |
| 980 } | 998 } |
| 981 | 999 |
| 982 DecodedDataDocumentParser::appendBytes(data, length); | 1000 DecodedDataDocumentParser::appendBytes(data, length); |
| 983 } | 1001 } |
| 984 | 1002 |
| 1003 void HTMLDocumentParser::parserResourceMessageFilterAdded() | |
| 1004 { | |
| 1005 if (isDetached()) | |
| 1006 return; | |
| 1007 | |
| 1008 ASSERT(m_parserThread && !needsDecoder()); | |
| 1009 // At this point the background parser will start receiving data chunks dire ctly | |
| 1010 // from the I/O thread and we no longer need to pass it any data. | |
| 1011 m_parserThreadIsStandalone = true; | |
| 1012 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::resourceFilter Added, m_backgroundParser))); | |
| 1013 } | |
| 1014 | |
| 985 void HTMLDocumentParser::flush() | 1015 void HTMLDocumentParser::flush() |
| 986 { | 1016 { |
| 987 // If we've got no decoder, we never received any data. | 1017 // If we've got no decoder, we never received any data. |
| 988 if (isDetached() || needsDecoder()) | 1018 if (isDetached() || needsDecoder()) |
| 989 return; | 1019 return; |
| 990 | 1020 |
| 991 if (m_haveBackgroundParser) | 1021 if (m_parserThread) |
| 992 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::flush, m_backgroundParser)); | 1022 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::flush, m_b ackgroundParser))); |
| 993 else | 1023 else |
| 994 DecodedDataDocumentParser::flush(); | 1024 DecodedDataDocumentParser::flush(); |
| 995 } | 1025 } |
| 996 | 1026 |
| 997 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) | 1027 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) |
| 998 { | 1028 { |
| 999 DecodedDataDocumentParser::setDecoder(decoder); | 1029 DecodedDataDocumentParser::setDecoder(decoder); |
| 1000 | 1030 |
| 1001 if (m_haveBackgroundParser) | 1031 if (m_parserThread) |
| 1002 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder())); | 1032 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::setDecoder , m_backgroundParser, takeDecoder()))); |
| 1003 } | 1033 } |
| 1004 | 1034 |
| 1005 } | 1035 } |
| OLD | NEW |