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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_opt ions)) | 109 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_opt ions)) |
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_isPinnedToMainThread(false) |
117 , m_endWasDelayed(false) | 117 , m_endWasDelayed(false) |
118 , m_haveBackgroundParser(false) | 118 , m_haveBackgroundParser(false) |
119 , m_tasksWereSuspended(false) | |
119 , m_pumpSessionNestingLevel(0) | 120 , m_pumpSessionNestingLevel(0) |
120 { | 121 { |
121 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); | 122 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); |
122 } | 123 } |
123 | 124 |
124 // FIXME: Member variables should be grouped into self-initializing structs to | 125 // FIXME: Member variables should be grouped into self-initializing structs to |
125 // minimize code duplication between these constructors. | 126 // minimize code duplication between these constructors. |
126 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont extElement, ParserContentPolicy parserContentPolicy) | 127 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont extElement, ParserContentPolicy parserContentPolicy) |
127 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) | 128 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) |
128 , m_options(&fragment->document()) | 129 , m_options(&fragment->document()) |
129 , m_token(adoptPtr(new HTMLToken)) | 130 , m_token(adoptPtr(new HTMLToken)) |
130 , m_tokenizer(HTMLTokenizer::create(m_options)) | 131 , m_tokenizer(HTMLTokenizer::create(m_options)) |
131 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this ->parserContentPolicy(), m_options)) | 132 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this ->parserContentPolicy(), m_options)) |
132 , m_xssAuditorDelegate(&fragment->document()) | 133 , m_xssAuditorDelegate(&fragment->document()) |
133 , m_weakFactory(this) | 134 , m_weakFactory(this) |
134 , m_isPinnedToMainThread(true) | 135 , m_isPinnedToMainThread(true) |
135 , m_endWasDelayed(false) | 136 , m_endWasDelayed(false) |
136 , m_haveBackgroundParser(false) | 137 , m_haveBackgroundParser(false) |
138 , m_tasksWereSuspended(false) | |
137 , m_pumpSessionNestingLevel(0) | 139 , m_pumpSessionNestingLevel(0) |
138 { | 140 { |
139 ASSERT(!shouldUseThreading()); | 141 ASSERT(!shouldUseThreading()); |
140 bool reportErrors = false; // For now document fragment parsing never report s errors. | 142 bool reportErrors = false; // For now document fragment parsing never report s errors. |
141 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report Errors, m_options)); | 143 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report Errors, m_options)); |
142 m_xssAuditor.initForFragment(); | 144 m_xssAuditor.initForFragment(); |
143 } | 145 } |
144 | 146 |
145 HTMLDocumentParser::~HTMLDocumentParser() | 147 HTMLDocumentParser::~HTMLDocumentParser() |
146 { | 148 { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
274 } | 276 } |
275 | 277 |
276 // Used by HTMLParserScheduler | 278 // Used by HTMLParserScheduler |
277 void HTMLDocumentParser::resumeParsingAfterYield() | 279 void HTMLDocumentParser::resumeParsingAfterYield() |
278 { | 280 { |
279 ASSERT(!m_isPinnedToMainThread); | 281 ASSERT(!m_isPinnedToMainThread); |
280 // pumpTokenizer can cause this parser to be detached from the Document, | 282 // pumpTokenizer can cause this parser to be detached from the Document, |
281 // but we need to ensure it isn't deleted yet. | 283 // but we need to ensure it isn't deleted yet. |
282 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); | 284 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); |
283 | 285 |
284 if (m_haveBackgroundParser) { | 286 if (m_haveBackgroundParser || !m_speculations.isEmpty()) { |
João Eiras
2014/10/06 12:14:30
I'm a bit unsure about how these two variables rel
eseidel
2014/10/06 18:07:08
Speculations are parsed chunks sent to us from the
João Eiras
2014/10/07 13:25:07
OK, line reverted.
| |
285 pumpPendingSpeculations(); | 287 pumpPendingSpeculations(); |
286 return; | 288 return; |
287 } | 289 } |
288 | 290 |
289 // We should never be here unless we can pump immediately. Call pumpTokeniz er() | 291 // We should never be here unless we can pump immediately. Call pumpTokeniz er() |
290 // directly so that ASSERTS will fire if we're wrong. | 292 // directly so that ASSERTS will fire if we're wrong. |
291 pumpTokenizer(AllowYield); | 293 if (m_tokenizer) |
João Eiras
2014/10/06 12:14:31
As consequence of forcing a call to this method wh
eseidel
2014/10/06 18:07:08
This seems wrong. We should just be more careful
João Eiras
2014/10/07 13:25:07
Ok, added a couple extra checks in HTMLDocumentPar
| |
294 pumpTokenizer(AllowYield); | |
292 endIfDelayed(); | 295 endIfDelayed(); |
293 } | 296 } |
294 | 297 |
295 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() | 298 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() |
296 { | 299 { |
297 ASSERT(scriptingContentIsAllowed(parserContentPolicy())); | 300 ASSERT(scriptingContentIsAllowed(parserContentPolicy())); |
298 | 301 |
299 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); | 302 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); |
300 RefPtrWillBeRawPtr<Element> scriptElement = m_treeBuilder->takeScriptToProce ss(scriptStartPosition); | 303 RefPtrWillBeRawPtr<Element> scriptElement = m_treeBuilder->takeScriptToProce ss(scriptStartPosition); |
301 // We will not have a scriptRunner when parsing a DocumentFragment. | 304 // We will not have a scriptRunner when parsing a DocumentFragment. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
342 return true; | 345 return true; |
343 } | 346 } |
344 | 347 |
345 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa rsedChunk> chunk) | 348 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa rsedChunk> chunk) |
346 { | 349 { |
347 TRACE_EVENT0("blink", "HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser"); | 350 TRACE_EVENT0("blink", "HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser"); |
348 | 351 |
349 // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops | 352 // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops |
350 // which can cause this method to be re-entered. We detect re-entry using | 353 // which can cause this method to be re-entered. We detect re-entry using |
351 // hasActiveParser(), save the chunk as a speculation, and return. | 354 // hasActiveParser(), save the chunk as a speculation, and return. |
352 if (isWaitingForScripts() || !m_speculations.isEmpty() || document()->active ParserCount() > 0) { | 355 if (isWaitingForScripts() || !m_speculations.isEmpty() || document()->active ParserCount() > 0 || m_tasksWereSuspended) { |
353 m_preloader->takeAndPreload(chunk->preloads); | 356 m_preloader->takeAndPreload(chunk->preloads); |
354 m_speculations.append(chunk); | 357 m_speculations.append(chunk); |
355 return; | 358 return; |
356 } | 359 } |
357 | 360 |
358 // processParsedChunkFromBackgroundParser can cause this parser to be detach ed from the Document, | 361 // processParsedChunkFromBackgroundParser can cause this parser to be detach ed from the Document, |
359 // but we need to ensure it isn't deleted yet. | 362 // but we need to ensure it isn't deleted yet. |
360 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); | 363 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); |
361 | 364 |
362 ASSERT(m_speculations.isEmpty()); | 365 ASSERT(m_speculations.isEmpty()); |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1022 { | 1025 { |
1023 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f ragment, contextElement, parserContentPolicy); | 1026 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f ragment, contextElement, parserContentPolicy); |
1024 parser->insert(source); // Use insert() so that the parser will not yield. | 1027 parser->insert(source); // Use insert() so that the parser will not yield. |
1025 parser->finish(); | 1028 parser->finish(); |
1026 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/ 3963151> | 1029 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/ 3963151> |
1027 parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction. | 1030 parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction. |
1028 } | 1031 } |
1029 | 1032 |
1030 void HTMLDocumentParser::suspendScheduledTasks() | 1033 void HTMLDocumentParser::suspendScheduledTasks() |
1031 { | 1034 { |
1035 ASSERT(!m_tasksWereSuspended); | |
1036 m_tasksWereSuspended = true; | |
1032 if (m_parserScheduler) | 1037 if (m_parserScheduler) |
1033 m_parserScheduler->suspend(); | 1038 m_parserScheduler->suspend(); |
1034 } | 1039 } |
1035 | 1040 |
1036 void HTMLDocumentParser::resumeScheduledTasks() | 1041 void HTMLDocumentParser::resumeScheduledTasks() |
1037 { | 1042 { |
1043 ASSERT(m_tasksWereSuspended); | |
1044 m_tasksWereSuspended = false; | |
1038 if (m_parserScheduler) | 1045 if (m_parserScheduler) |
1039 m_parserScheduler->resume(); | 1046 m_parserScheduler->scheduleForResume(); |
1040 } | 1047 } |
1041 | 1048 |
1042 void HTMLDocumentParser::appendBytes(const char* data, size_t length) | 1049 void HTMLDocumentParser::appendBytes(const char* data, size_t length) |
1043 { | 1050 { |
1044 if (!length || isStopped()) | 1051 if (!length || isStopped()) |
1045 return; | 1052 return; |
1046 | 1053 |
1047 if (shouldUseThreading()) { | 1054 if (shouldUseThreading()) { |
1048 if (!m_haveBackgroundParser) | 1055 if (!m_haveBackgroundParser) |
1049 startBackgroundParser(); | 1056 startBackgroundParser(); |
(...skipping 24 matching lines...) Expand all Loading... | |
1074 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) | 1081 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) |
1075 { | 1082 { |
1076 ASSERT(decoder); | 1083 ASSERT(decoder); |
1077 DecodedDataDocumentParser::setDecoder(decoder); | 1084 DecodedDataDocumentParser::setDecoder(decoder); |
1078 | 1085 |
1079 if (m_haveBackgroundParser) | 1086 if (m_haveBackgroundParser) |
1080 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder())); | 1087 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder())); |
1081 } | 1088 } |
1082 | 1089 |
1083 } | 1090 } |
OLD | NEW |