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

Unified Diff: sky/engine/core/html/parser/HTMLDocumentParser.cpp

Issue 664573004: Live the dream (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: DEPS 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/engine/core/html/parser/HTMLDocumentParser.h ('k') | sky/engine/core/html/parser/HTMLParserOptions.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/engine/core/html/parser/HTMLDocumentParser.cpp
diff --git a/sky/engine/core/html/parser/HTMLDocumentParser.cpp b/sky/engine/core/html/parser/HTMLDocumentParser.cpp
index 9006dab0d4f99c45018c16167398ac6da70a8b17..ee6ebc93975ee041221e8f4ddd83b9df9fb38316 100644
--- a/sky/engine/core/html/parser/HTMLDocumentParser.cpp
+++ b/sky/engine/core/html/parser/HTMLDocumentParser.cpp
@@ -48,8 +48,6 @@ namespace blink {
HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors)
: DecodedDataDocumentParser(document)
, m_options(&document)
- , m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken))
- , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_options))
, m_treeBuilder(HTMLTreeBuilder::create(this, &document, reportErrors, m_options))
, m_parserScheduler(HTMLParserScheduler::create(this))
, m_weakFactory(this)
@@ -58,7 +56,7 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors
, m_haveBackgroundParser(false)
, m_pumpSessionNestingLevel(0)
{
- ASSERT(shouldUseThreading() || (m_token && m_tokenizer));
+ ASSERT(shouldUseThreading());
}
HTMLDocumentParser::~HTMLDocumentParser()
@@ -84,6 +82,23 @@ void HTMLDocumentParser::trace(Visitor* visitor)
DecodedDataDocumentParser::trace(visitor);
}
+void HTMLDocumentParser::parse(mojo::ScopedDataPipeConsumerHandle source)
+{
+ ASSERT(!isStopped());
+ ASSERT(shouldUseThreading());
+ ASSERT(!m_haveBackgroundParser);
+ m_haveBackgroundParser = true;
+
+ OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new BackgroundHTMLParser::Configuration);
+ config->options = m_options;
+ config->source = source.Pass();
+ config->parser = m_weakFactory.createWeakPtr();
+
+ m_backgroundParser = BackgroundHTMLParser::create(config.release());
+ HTMLParserThread::taskRunner()->PostTask(FROM_HERE,
+ base::Bind(&BackgroundHTMLParser::start, m_backgroundParser));
+}
+
void HTMLDocumentParser::detach()
{
if (m_haveBackgroundParser)
@@ -115,13 +130,6 @@ void HTMLDocumentParser::prepareToStopParsing()
// but we need to ensure it isn't deleted yet.
RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
- // NOTE: This pump should only ever emit buffered character tokens,
- // so ForceSynchronous vs. AllowYield should be meaningless.
- if (m_tokenizer) {
- ASSERT(!m_haveBackgroundParser);
- pumpTokenizerIfPossible(ForceSynchronous);
- }
-
if (isStopped())
return;
@@ -151,22 +159,6 @@ bool HTMLDocumentParser::processingData() const
return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser;
}
-void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)
-{
- if (isStopped())
- return;
- if (isWaitingForScripts())
- return;
-
- // Once a resume is scheduled, HTMLParserScheduler controls when we next pump.
- if (isScheduledForResume()) {
- ASSERT(mode == AllowYield);
- return;
- }
-
- pumpTokenizer(mode);
-}
-
bool HTMLDocumentParser::isScheduledForResume() const
{
return m_parserScheduler && m_parserScheduler->isScheduledForResume();
@@ -179,15 +171,8 @@ void HTMLDocumentParser::resumeParsingAfterYield()
// but we need to ensure it isn't deleted yet.
RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
- if (m_haveBackgroundParser) {
- pumpPendingSpeculations();
- return;
- }
-
- // We should never be here unless we can pump immediately. Call pumpTokenizer()
- // directly so that ASSERTS will fire if we're wrong.
- pumpTokenizer(AllowYield);
- endIfDelayed();
+ ASSERT(m_haveBackgroundParser);
+ pumpPendingSpeculations();
}
void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
@@ -199,35 +184,6 @@ void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
m_scriptRunner.runScript(toHTMLScriptElement(scriptToProcess.get()), scriptStartPosition);
}
-bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& session)
-{
- if (isStopped())
- return false;
-
- ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
-
- if (isWaitingForScripts()) {
- if (mode == AllowYield)
- session.didSeeScript = true;
-
- // If we don't run the script, we cannot allow the next token to be taken.
- if (session.needsYield)
- return false;
-
- // If we're paused waiting for a script, we try to execute scripts before continuing.
- runScriptsForPausedTreeBuilder();
- if (isStopped())
- return false;
- if (isWaitingForScripts())
- return false;
- }
-
- if (mode == AllowYield)
- m_parserScheduler->checkForYieldBeforeToken(session);
-
- return true;
-}
-
void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk> chunk)
{
TRACE_EVENT0("blink", "HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser");
@@ -276,8 +232,6 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
ASSERT(refCount() >= 2);
#endif
ASSERT(shouldUseThreading());
- ASSERT(!m_tokenizer);
- ASSERT(!m_token);
ASSERT(!m_lastChunkBeforeScript);
ActiveParserSession session(contextForParsingSession());
@@ -308,9 +262,6 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
prepareToStopParsing();
break;
}
-
- ASSERT(!m_tokenizer);
- ASSERT(!m_token);
}
// Make sure any pending text nodes are emitted before returning.
@@ -327,10 +278,6 @@ void HTMLDocumentParser::pumpPendingSpeculations()
// ASSERT that this object is both attached to the Document and protected.
ASSERT(refCount() >= 2);
#endif
- // If this assert fails, you need to call validateSpeculations to make sure
- // m_tokenizer and m_token don't have state that invalidates m_speculations.
- ASSERT(!m_tokenizer);
- ASSERT(!m_token);
ASSERT(!m_lastChunkBeforeScript);
ASSERT(!isWaitingForScripts());
ASSERT(!isStopped());
@@ -367,52 +314,6 @@ Document* HTMLDocumentParser::contextForParsingSession()
return document();
}
-void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
-{
- ASSERT(!isStopped());
- ASSERT(!isScheduledForResume());
-#if !ENABLE(OILPAN)
- // ASSERT that this object is both attached to the Document and protected.
- ASSERT(refCount() >= 2);
-#endif
- ASSERT(m_tokenizer);
- ASSERT(m_token);
- ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
-
- PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession());
-
- TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "beginData", InspectorParseHtmlEvent::beginData(document(), m_input.current().currentLine().zeroBasedInt()));
- TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
-
- while (canTakeNextToken(mode, session) && !session.needsYield) {
- if (!m_tokenizer->nextToken(m_input.current(), token()))
- break;
-
- constructTreeFromHTMLToken(token());
- ASSERT(token().isUninitialized());
- }
-
-#if !ENABLE(OILPAN)
- // Ensure we haven't been totally deref'ed after pumping. Any caller of this
- // function should be holding a RefPtr to this to ensure we weren't deleted.
- ASSERT(refCount() >= 1);
-#endif
-
- if (isStopped())
- return;
-
- // There should only be PendingText left since the tree-builder always flushes
- // the task queue before returning. In case that ever changes, crash.
- if (mode == ForceSynchronous)
- m_treeBuilder->flush();
- RELEASE_ASSERT(!isStopped());
-
- if (session.needsYield)
- m_parserScheduler->scheduleForResume();
-
- TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "endLine", m_input.current().currentLine().zeroBasedInt());
-}
-
void HTMLDocumentParser::constructTreeFromHTMLToken(HTMLToken& rawToken)
{
AtomicHTMLToken token(rawToken);
@@ -446,47 +347,11 @@ void HTMLDocumentParser::constructTreeFromCompactHTMLToken(const CompactHTMLToke
bool HTMLDocumentParser::hasInsertionPoint()
{
- return m_input.hasInsertionPoint();
-}
-
-void HTMLDocumentParser::insert(const SegmentedString& source)
-{
- if (isStopped())
- return;
-
- TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", source.length());
-
- // pumpTokenizer can cause this parser to be detached from the Document,
- // but we need to ensure it isn't deleted yet.
- RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
-
- if (!m_tokenizer) {
- ASSERT(!inPumpSession());
- ASSERT(m_haveBackgroundParser);
- m_token = adoptPtr(new HTMLToken);
- m_tokenizer = HTMLTokenizer::create(m_options);
- }
-
- SegmentedString excludedLineNumberSource(source);
- excludedLineNumberSource.setExcludeLineNumbers();
- m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
- pumpTokenizerIfPossible(ForceSynchronous);
-
- endIfDelayed();
+ return false;
}
void HTMLDocumentParser::startBackgroundParser()
{
- ASSERT(!isStopped());
- ASSERT(shouldUseThreading());
- ASSERT(!m_haveBackgroundParser);
- m_haveBackgroundParser = true;
-
- OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new BackgroundHTMLParser::Configuration);
- config->options = m_options;
- config->parser = m_weakFactory.createWeakPtr();
-
- m_backgroundParser = BackgroundHTMLParser::create(config.release());
}
void HTMLDocumentParser::stopBackgroundParser()
@@ -500,35 +365,6 @@ void HTMLDocumentParser::stopBackgroundParser()
m_weakFactory.revokeAll();
}
-void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
-{
- if (isStopped())
- return;
-
- // We should never reach this point if we're using a parser thread,
- // as appendBytes() will directly ship the data to the thread.
- ASSERT(!shouldUseThreading());
-
- // pumpTokenizer can cause this parser to be detached from the Document,
- // but we need to ensure it isn't deleted yet.
- RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
- TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->length());
- String source(inputSource);
-
- m_input.appendToEnd(source);
-
- if (inPumpSession()) {
- // We've gotten data off the network in a nested write.
- // We don't want to consume any more of the input stream now. Do
- // not worry. We'll consume this data in a less-nested write().
- return;
- }
-
- pumpTokenizerIfPossible(AllowYield);
-
- endIfDelayed();
-}
-
void HTMLDocumentParser::end()
{
ASSERT(!isDetached());
@@ -543,9 +379,6 @@ void HTMLDocumentParser::end()
void HTMLDocumentParser::attemptToEnd()
{
- // finish() indicates we will not receive any more data. If we are waiting on
- // an external script to load, we can't finish parsing quite yet.
-
if (shouldDelayEnd()) {
m_endWasDelayed = true;
return;
@@ -566,47 +399,6 @@ void HTMLDocumentParser::endIfDelayed()
prepareToStopParsing();
}
-void HTMLDocumentParser::finish()
-{
- // FIXME: We should ASSERT(!m_parserStopped) here, since it does not
- // makes sense to call any methods on DocumentParser once it's been stopped.
- // However, FrameLoader::stop calls DocumentParser::finish unconditionally.
-
- // flush may ending up executing arbitrary script, and possibly detach the parser.
- RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
- flush();
- if (isDetached())
- return;
-
- // Empty documents never got an append() call, and thus have never started
- // a background parser. In those cases, we ignore shouldUseThreading()
- // and fall through to the non-threading case.
- if (m_haveBackgroundParser) {
- if (!m_input.haveSeenEndOfFile())
- m_input.closeWithoutMarkingEndOfFile();
- HTMLParserThread::taskRunner()->PostTask(FROM_HERE,
- base::Bind(&BackgroundHTMLParser::finish, m_backgroundParser));
- return;
- }
-
- if (!m_tokenizer) {
- ASSERT(!m_token);
- // We're finishing before receiving any data. Rather than booting up
- // the background parser just to spin it down, we finish parsing
- // synchronously.
- m_token = adoptPtr(new HTMLToken);
- m_tokenizer = HTMLTokenizer::create(m_options);
- }
-
- // We're not going to get any more data off the network, so we tell the
- // input stream we've reached the end of file. finish() can be called more
- // than once, if the first time does not call end().
- if (!m_input.haveSeenEndOfFile())
- m_input.markEndOfFile();
-
- attemptToEnd();
-}
-
bool HTMLDocumentParser::isExecutingScript() const
{
return m_scriptRunner.isExecutingScript();
@@ -614,22 +406,14 @@ bool HTMLDocumentParser::isExecutingScript() const
OrdinalNumber HTMLDocumentParser::lineNumber() const
{
- if (m_haveBackgroundParser)
- return m_textPosition.m_line;
-
- return m_input.current().currentLine();
+ ASSERT(m_haveBackgroundParser);
+ return m_textPosition.m_line;
}
TextPosition HTMLDocumentParser::textPosition() const
{
- if (m_haveBackgroundParser)
- return m_textPosition;
-
- const SegmentedString& currentString = m_input.current();
- OrdinalNumber line = currentString.currentLine();
- OrdinalNumber column = currentString.currentColumn();
-
- return TextPosition(line, column);
+ ASSERT(m_haveBackgroundParser);
+ return m_textPosition;
}
bool HTMLDocumentParser::isWaitingForScripts() const
@@ -641,19 +425,14 @@ void HTMLDocumentParser::resumeParsingAfterScriptExecution()
{
ASSERT(!isExecutingScript());
ASSERT(!isWaitingForScripts());
+ ASSERT(m_haveBackgroundParser);
- if (m_haveBackgroundParser) {
- validateSpeculations(m_lastChunkBeforeScript.release());
- ASSERT(!m_lastChunkBeforeScript);
- // processParsedChunkFromBackgroundParser can cause this parser to be detached from the Document,
- // but we need to ensure it isn't deleted yet.
- RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
- pumpPendingSpeculations();
- return;
- }
-
- pumpTokenizerIfPossible(AllowYield);
- endIfDelayed();
+ validateSpeculations(m_lastChunkBeforeScript.release());
+ ASSERT(!m_lastChunkBeforeScript);
+ // processParsedChunkFromBackgroundParser can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
+ pumpPendingSpeculations();
}
void HTMLDocumentParser::executeScriptsWaitingForResources()
@@ -666,39 +445,4 @@ void HTMLDocumentParser::executeScriptsWaitingForResources()
resumeParsingAfterScriptExecution();
}
-void HTMLDocumentParser::appendBytes(const char* data, size_t length)
-{
- if (!length || isStopped())
- return;
-
- if (shouldUseThreading()) {
- if (!m_haveBackgroundParser)
- startBackgroundParser();
-
- OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length));
- memcpy(buffer->data(), data, length);
- TRACE_EVENT1("net", "HTMLDocumentParser::appendBytes", "size", (unsigned)length);
-
- HTMLParserThread::taskRunner()->PostTask(FROM_HERE,
- base::Bind(&BackgroundHTMLParser::appendRawBytesFromMainThread, m_backgroundParser, buffer.release()));
- return;
- }
-
- DecodedDataDocumentParser::appendBytes(data, length);
-}
-
-void HTMLDocumentParser::flush()
-{
- // If we've got no decoder, we never received any data.
- if (isDetached())
- return;
-
- if (m_haveBackgroundParser) {
- HTMLParserThread::taskRunner()->PostTask(FROM_HERE,
- base::Bind(&BackgroundHTMLParser::flush, m_backgroundParser));
- } else {
- DecodedDataDocumentParser::flush();
- }
-}
-
}
« no previous file with comments | « sky/engine/core/html/parser/HTMLDocumentParser.h ('k') | sky/engine/core/html/parser/HTMLParserOptions.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698