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

Side by Side Diff: Source/core/html/parser/HTMLDocumentParser.cpp

Issue 659713002: Remove SynchronousMode, as it is always ForceSynchronous. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebased Created 6 years, 2 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 void HTMLDocumentParser::prepareToStopParsing() 212 void HTMLDocumentParser::prepareToStopParsing()
213 { 213 {
214 // FIXME: It may not be correct to disable this for the background parser. 214 // FIXME: It may not be correct to disable this for the background parser.
215 // That means hasInsertionPoint() may not be correct in some cases. 215 // That means hasInsertionPoint() may not be correct in some cases.
216 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); 216 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser);
217 217
218 // pumpTokenizer can cause this parser to be detached from the Document, 218 // pumpTokenizer can cause this parser to be detached from the Document,
219 // but we need to ensure it isn't deleted yet. 219 // but we need to ensure it isn't deleted yet.
220 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); 220 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
221 221
222 // NOTE: This pump should only ever emit buffered character tokens, 222 // NOTE: This pump should only ever emit buffered character tokens.
223 // so ForceSynchronous vs. AllowYield should be meaningless.
224 if (m_tokenizer) { 223 if (m_tokenizer) {
225 ASSERT(!m_haveBackgroundParser); 224 ASSERT(!m_haveBackgroundParser);
226 pumpTokenizerIfPossible(ForceSynchronous); 225 pumpTokenizerIfPossible();
227 } 226 }
228 227
229 if (isStopped()) 228 if (isStopped())
230 return; 229 return;
231 230
232 DocumentParser::prepareToStopParsing(); 231 DocumentParser::prepareToStopParsing();
233 232
234 // We will not have a scriptRunner when parsing a DocumentFragment. 233 // We will not have a scriptRunner when parsing a DocumentFragment.
235 if (m_scriptRunner) 234 if (m_scriptRunner)
236 document()->setReadyState(Document::Interactive); 235 document()->setReadyState(Document::Interactive);
237 236
238 // Setting the ready state above can fire mutation event and detach us 237 // Setting the ready state above can fire mutation event and detach us
239 // from underneath. In that case, just bail out. 238 // from underneath. In that case, just bail out.
240 if (isDetached()) 239 if (isDetached())
241 return; 240 return;
242 241
243 attemptToRunDeferredScriptsAndEnd(); 242 attemptToRunDeferredScriptsAndEnd();
244 } 243 }
245 244
246 bool HTMLDocumentParser::isParsingFragment() const 245 bool HTMLDocumentParser::isParsingFragment() const
247 { 246 {
248 return m_treeBuilder->isParsingFragment(); 247 return m_treeBuilder->isParsingFragment();
249 } 248 }
250 249
251 bool HTMLDocumentParser::processingData() const 250 bool HTMLDocumentParser::processingData() const
252 { 251 {
253 return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser; 252 return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser;
254 } 253 }
255 254
256 void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode) 255 void HTMLDocumentParser::pumpTokenizerIfPossible()
257 { 256 {
258 ASSERT(mode == ForceSynchronous);
259
260 if (isStopped()) 257 if (isStopped())
261 return; 258 return;
262 if (isWaitingForScripts()) 259 if (isWaitingForScripts())
263 return; 260 return;
264 261
265 // Once a resume is scheduled, HTMLParserScheduler controls when we next pum p. 262 // Once a resume is scheduled, HTMLParserScheduler controls when we next pum p.
266 if (isScheduledForResume()) { 263 if (isScheduledForResume()) {
267 return; 264 return;
268 } 265 }
269 266
270 pumpTokenizer(mode); 267 pumpTokenizer();
271 } 268 }
272 269
273 bool HTMLDocumentParser::isScheduledForResume() const 270 bool HTMLDocumentParser::isScheduledForResume() const
274 { 271 {
275 return m_parserScheduler && m_parserScheduler->isScheduledForResume(); 272 return m_parserScheduler && m_parserScheduler->isScheduledForResume();
276 } 273 }
277 274
278 // Used by HTMLParserScheduler 275 // Used by HTMLParserScheduler
279 void HTMLDocumentParser::resumeParsingAfterYield() 276 void HTMLDocumentParser::resumeParsingAfterYield()
280 { 277 {
(...skipping 10 matching lines...) Expand all
291 { 288 {
292 ASSERT(scriptingContentIsAllowed(parserContentPolicy())); 289 ASSERT(scriptingContentIsAllowed(parserContentPolicy()));
293 290
294 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); 291 TextPosition scriptStartPosition = TextPosition::belowRangePosition();
295 RefPtrWillBeRawPtr<Element> scriptElement = m_treeBuilder->takeScriptToProce ss(scriptStartPosition); 292 RefPtrWillBeRawPtr<Element> scriptElement = m_treeBuilder->takeScriptToProce ss(scriptStartPosition);
296 // We will not have a scriptRunner when parsing a DocumentFragment. 293 // We will not have a scriptRunner when parsing a DocumentFragment.
297 if (m_scriptRunner) 294 if (m_scriptRunner)
298 m_scriptRunner->execute(scriptElement.release(), scriptStartPosition); 295 m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
299 } 296 }
300 297
301 bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses sion) 298 bool HTMLDocumentParser::canTakeNextToken(PumpSession& session)
302 { 299 {
303 if (isStopped()) 300 if (isStopped())
304 return false; 301 return false;
305 302
306 ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
307
308 if (isWaitingForScripts()) { 303 if (isWaitingForScripts()) {
309 if (mode == AllowYield)
310 session.didSeeScript = true;
311
312 // If we don't run the script, we cannot allow the next token to be take n. 304 // If we don't run the script, we cannot allow the next token to be take n.
313 if (session.needsYield) 305 if (session.needsYield)
314 return false; 306 return false;
315 307
316 // If we're paused waiting for a script, we try to execute scripts befor e continuing. 308 // If we're paused waiting for a script, we try to execute scripts befor e continuing.
317 runScriptsForPausedTreeBuilder(); 309 runScriptsForPausedTreeBuilder();
318 if (isStopped()) 310 if (isStopped())
319 return false; 311 return false;
320 if (isWaitingForScripts()) 312 if (isWaitingForScripts())
321 return false; 313 return false;
322 } 314 }
323 315
324 // FIXME: It's wrong for the HTMLDocumentParser to reach back to the 316 // FIXME: It's wrong for the HTMLDocumentParser to reach back to the
325 // LocalFrame, but this approach is how the old parser handled 317 // LocalFrame, but this approach is how the old parser handled
326 // stopping when the page assigns window.location. What really 318 // stopping when the page assigns window.location. What really
327 // should happen is that assigning window.location causes the 319 // should happen is that assigning window.location causes the
328 // parser to stop parsing cleanly. The problem is we're not 320 // parser to stop parsing cleanly. The problem is we're not
329 // perpared to do that at every point where we run JavaScript. 321 // perpared to do that at every point where we run JavaScript.
330 if (!isParsingFragment() 322 if (!isParsingFragment()
331 && document()->frame() && document()->frame()->navigationScheduler().loc ationChangePending()) 323 && document()->frame() && document()->frame()->navigationScheduler().loc ationChangePending())
332 return false; 324 return false;
333 325
334 if (mode == AllowYield)
335 m_parserScheduler->checkForYieldBeforeToken(session);
336
337 return true; 326 return true;
338 } 327 }
339 328
340 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa rsedChunk> chunk) 329 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa rsedChunk> chunk)
341 { 330 {
342 TRACE_EVENT0("blink", "HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser"); 331 TRACE_EVENT0("blink", "HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser");
343 332
344 // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops 333 // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops
345 // which can cause this method to be re-entered. We detect re-entry using 334 // which can cause this method to be re-entered. We detect re-entry using
346 // hasActiveParser(), save the chunk as a speculation, and return. 335 // hasActiveParser(), save the chunk as a speculation, and return.
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 } 555 }
567 556
568 static PassRefPtr<MediaValues> createMediaValues(Document* document) 557 static PassRefPtr<MediaValues> createMediaValues(Document* document)
569 { 558 {
570 ASSERT(document); 559 ASSERT(document);
571 RefPtr<MediaValues> mediaValues = MediaValuesCached::create(*document); 560 RefPtr<MediaValues> mediaValues = MediaValuesCached::create(*document);
572 ASSERT(mediaValues->isSafeToSendToAnotherThread()); 561 ASSERT(mediaValues->isSafeToSendToAnotherThread());
573 return mediaValues; 562 return mediaValues;
574 } 563 }
575 564
576 void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) 565 void HTMLDocumentParser::pumpTokenizer()
577 { 566 {
578 ASSERT(!isStopped()); 567 ASSERT(!isStopped());
579 ASSERT(!isScheduledForResume()); 568 ASSERT(!isScheduledForResume());
580 #if !ENABLE(OILPAN) 569 #if !ENABLE(OILPAN)
581 // ASSERT that this object is both attached to the Document and protected. 570 // ASSERT that this object is both attached to the Document and protected.
582 ASSERT(refCount() >= 2); 571 ASSERT(refCount() >= 2);
583 #endif 572 #endif
584 ASSERT(m_tokenizer); 573 ASSERT(m_tokenizer);
585 ASSERT(m_token); 574 ASSERT(m_token);
586 ASSERT(mode == ForceSynchronous);
587 575
588 PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession()); 576 PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession());
589 577
590 // We tell the InspectorInstrumentation about every pump, even if we 578 // We tell the InspectorInstrumentation about every pump, even if we
591 // end up pumping nothing. It can filter out empty pumps itself. 579 // end up pumping nothing. It can filter out empty pumps itself.
592 // FIXME: m_input.current().length() is only accurate if we 580 // FIXME: m_input.current().length() is only accurate if we
593 // end up parsing the whole buffer in this pump. We should pass how 581 // end up parsing the whole buffer in this pump. We should pass how
594 // much we parsed as part of didWriteHTML instead of willWriteHTML. 582 // much we parsed as part of didWriteHTML instead of willWriteHTML.
595 TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTM L", "beginData", InspectorParseHtmlEvent::beginData(document(), m_input.current( ).currentLine().zeroBasedInt())); 583 TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTM L", "beginData", InspectorParseHtmlEvent::beginData(document(), m_input.current( ).currentLine().zeroBasedInt()));
596 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), " CallStack", "stack", InspectorCallStackEvent::currentCallStack()); 584 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), " CallStack", "stack", InspectorCallStackEvent::currentCallStack());
597 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli ne migrates to tracing. 585 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli ne migrates to tracing.
598 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteH TML(document(), m_input.current().currentLine().zeroBasedInt()); 586 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteH TML(document(), m_input.current().currentLine().zeroBasedInt());
599 587
600 m_xssAuditor.init(document(), &m_xssAuditorDelegate); 588 m_xssAuditor.init(document(), &m_xssAuditorDelegate);
601 589
602 while (canTakeNextToken(mode, session) && !session.needsYield) { 590 while (canTakeNextToken(session) && !session.needsYield) {
603 if (!isParsingFragment()) 591 if (!isParsingFragment())
604 m_sourceTracker.start(m_input.current(), m_tokenizer.get(), token()) ; 592 m_sourceTracker.start(m_input.current(), m_tokenizer.get(), token()) ;
605 593
606 if (!m_tokenizer->nextToken(m_input.current(), token())) 594 if (!m_tokenizer->nextToken(m_input.current(), token()))
607 break; 595 break;
608 596
609 if (!isParsingFragment()) { 597 if (!isParsingFragment()) {
610 m_sourceTracker.end(m_input.current(), m_tokenizer.get(), token()); 598 m_sourceTracker.end(m_input.current(), m_tokenizer.get(), token());
611 599
612 // We do not XSS filter innerHTML, which means we (intentionally) fa il 600 // We do not XSS filter innerHTML, which means we (intentionally) fa il
(...skipping 10 matching lines...) Expand all
623 // Ensure we haven't been totally deref'ed after pumping. Any caller of this 611 // Ensure we haven't been totally deref'ed after pumping. Any caller of this
624 // function should be holding a RefPtr to this to ensure we weren't deleted. 612 // function should be holding a RefPtr to this to ensure we weren't deleted.
625 ASSERT(refCount() >= 1); 613 ASSERT(refCount() >= 1);
626 #endif 614 #endif
627 615
628 if (isStopped()) 616 if (isStopped())
629 return; 617 return;
630 618
631 // There should only be PendingText left since the tree-builder always flush es 619 // There should only be PendingText left since the tree-builder always flush es
632 // the task queue before returning. In case that ever changes, crash. 620 // the task queue before returning. In case that ever changes, crash.
633 if (mode == ForceSynchronous) 621 m_treeBuilder->flush(FlushAlways);
634 m_treeBuilder->flush(FlushAlways);
635 RELEASE_ASSERT(!isStopped()); 622 RELEASE_ASSERT(!isStopped());
636 623
637 if (session.needsYield) 624 if (session.needsYield)
638 m_parserScheduler->scheduleForResume(); 625 m_parserScheduler->scheduleForResume();
639 626
640 if (isWaitingForScripts()) { 627 if (isWaitingForScripts()) {
641 ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState); 628 ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
642 if (!m_preloadScanner) { 629 if (!m_preloadScanner) {
643 m_preloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, docume nt()->url(), createMediaValues(document()))); 630 m_preloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, docume nt()->url(), createMediaValues(document())));
644 m_preloadScanner->appendToEnd(m_input.current()); 631 m_preloadScanner->appendToEnd(m_input.current());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 if (!m_tokenizer) { 693 if (!m_tokenizer) {
707 ASSERT(!inPumpSession()); 694 ASSERT(!inPumpSession());
708 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); 695 ASSERT(m_haveBackgroundParser || wasCreatedByScript());
709 m_token = adoptPtr(new HTMLToken); 696 m_token = adoptPtr(new HTMLToken);
710 m_tokenizer = HTMLTokenizer::create(m_options); 697 m_tokenizer = HTMLTokenizer::create(m_options);
711 } 698 }
712 699
713 SegmentedString excludedLineNumberSource(source); 700 SegmentedString excludedLineNumberSource(source);
714 excludedLineNumberSource.setExcludeLineNumbers(); 701 excludedLineNumberSource.setExcludeLineNumbers();
715 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); 702 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
716 pumpTokenizerIfPossible(ForceSynchronous); 703 pumpTokenizerIfPossible();
717 704
718 if (isWaitingForScripts()) { 705 if (isWaitingForScripts()) {
719 // Check the document.write() output with a separate preload scanner as 706 // Check the document.write() output with a separate preload scanner as
720 // the main scanner can't deal with insertions. 707 // the main scanner can't deal with insertions.
721 if (!m_insertionPreloadScanner) 708 if (!m_insertionPreloadScanner)
722 m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_option s, document()->url(), createMediaValues(document()))); 709 m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_option s, document()->url(), createMediaValues(document())));
723 710
724 m_insertionPreloadScanner->appendToEnd(source); 711 m_insertionPreloadScanner->appendToEnd(source);
725 m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseEleme ntURL()); 712 m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseEleme ntURL());
726 } 713 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 // not worry. We'll consume this data in a less-nested write(). 789 // not worry. We'll consume this data in a less-nested write().
803 return; 790 return;
804 } 791 }
805 792
806 // A couple pinToMainThread() callers require synchronous parsing, but can't 793 // A couple pinToMainThread() callers require synchronous parsing, but can't
807 // easily use the insert() method, so we hack append() for them to be synchr onous. 794 // easily use the insert() method, so we hack append() for them to be synchr onous.
808 // javascript: url handling is one such caller. 795 // javascript: url handling is one such caller.
809 // FIXME: This is gross, and we should separate the concept of synchronous p arsing 796 // FIXME: This is gross, and we should separate the concept of synchronous p arsing
810 // from insert() so that only document.write() uses insert. 797 // from insert() so that only document.write() uses insert.
811 ASSERT(m_isPinnedToMainThread); 798 ASSERT(m_isPinnedToMainThread);
812 pumpTokenizerIfPossible(ForceSynchronous); 799 pumpTokenizerIfPossible();
813 800
814 endIfDelayed(); 801 endIfDelayed();
815 } 802 }
816 803
817 void HTMLDocumentParser::end() 804 void HTMLDocumentParser::end()
818 { 805 {
819 ASSERT(!isDetached()); 806 ASSERT(!isDetached());
820 ASSERT(!isScheduledForResume()); 807 ASSERT(!isScheduledForResume());
821 808
822 if (m_haveBackgroundParser) 809 if (m_haveBackgroundParser)
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 validateSpeculations(m_lastChunkBeforeScript.release()); 943 validateSpeculations(m_lastChunkBeforeScript.release());
957 ASSERT(!m_lastChunkBeforeScript); 944 ASSERT(!m_lastChunkBeforeScript);
958 // processParsedChunkFromBackgroundParser can cause this parser to be de tached from the Document, 945 // processParsedChunkFromBackgroundParser can cause this parser to be de tached from the Document,
959 // but we need to ensure it isn't deleted yet. 946 // but we need to ensure it isn't deleted yet.
960 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); 947 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
961 pumpPendingSpeculations(); 948 pumpPendingSpeculations();
962 return; 949 return;
963 } 950 }
964 951
965 m_insertionPreloadScanner.clear(); 952 m_insertionPreloadScanner.clear();
966 pumpTokenizerIfPossible(ForceSynchronous); 953 pumpTokenizerIfPossible();
967 endIfDelayed(); 954 endIfDelayed();
968 } 955 }
969 956
970 void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan() 957 void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan()
971 { 958 {
972 ASSERT(m_preloadScanner); 959 ASSERT(m_preloadScanner);
973 m_preloadScanner->appendToEnd(m_input.current()); 960 m_preloadScanner->appendToEnd(m_input.current());
974 m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL()); 961 m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
975 } 962 }
976 963
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) 1054 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
1068 { 1055 {
1069 ASSERT(decoder); 1056 ASSERT(decoder);
1070 DecodedDataDocumentParser::setDecoder(decoder); 1057 DecodedDataDocumentParser::setDecoder(decoder);
1071 1058
1072 if (m_haveBackgroundParser) 1059 if (m_haveBackgroundParser)
1073 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder())); 1060 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder()));
1074 } 1061 }
1075 1062
1076 } 1063 }
OLDNEW
« no previous file with comments | « Source/core/html/parser/HTMLDocumentParser.h ('k') | Source/core/html/parser/HTMLParserScheduler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698