| 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 |