Bug 959150 part 4 - Avoid using tree ops when parsing with nsHtml5StringParser. r=smaug.

This commit is contained in:
Henri Sivonen
2014-03-05 21:38:50 +02:00
parent 9c5e892c4f
commit d07d56d994
16 changed files with 638 additions and 301 deletions

View File

@@ -14,8 +14,8 @@
NS_IMPL_ISUPPORTS0(nsHtml5StringParser)
nsHtml5StringParser::nsHtml5StringParser()
: mExecutor(new nsHtml5TreeOpExecutor(true))
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor, nullptr))
: mBuilder(new nsHtml5OplessBuilder())
, mTreeBuilder(new nsHtml5TreeBuilder(mBuilder))
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, false))
{
MOZ_COUNT_CTOR(nsHtml5StringParser);
@@ -42,10 +42,9 @@ nsHtml5StringParser::ParseFragment(const nsAString& aSourceBuffer,
nsIURI* uri = doc->GetDocumentURI();
NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE);
nsIContent* target = aTargetNode;
mTreeBuilder->setFragmentContext(aContextLocalName,
aContextNamespace,
&target,
aTargetNode,
aQuirks);
#ifdef DEBUG
@@ -61,8 +60,7 @@ nsHtml5StringParser::ParseFragment(const nsAString& aSourceBuffer,
mTreeBuilder->SetPreventScriptExecution(aPreventScriptExecution);
Tokenize(aSourceBuffer, doc, true);
return NS_OK;
return Tokenize(aSourceBuffer, doc, true);
}
nsresult
@@ -82,28 +80,28 @@ nsHtml5StringParser::ParseDocument(const nsAString& aSourceBuffer,
mTreeBuilder->SetPreventScriptExecution(true);
Tokenize(aSourceBuffer, aTargetDoc, aScriptingEnabledForNoscriptParsing);
return NS_OK;
return Tokenize(aSourceBuffer, aTargetDoc, aScriptingEnabledForNoscriptParsing);
}
void
nsresult
nsHtml5StringParser::Tokenize(const nsAString& aSourceBuffer,
nsIDocument* aDocument,
bool aScriptingEnabledForNoscriptParsing) {
nsIURI* uri = aDocument->GetDocumentURI();
mExecutor->Init(aDocument, uri, nullptr, nullptr);
mBuilder->Init(aDocument, uri, nullptr, nullptr);
mExecutor->SetParser(this);
mExecutor->SetNodeInfoManager(aDocument->NodeInfoManager());
mBuilder->SetParser(this);
mBuilder->SetNodeInfoManager(aDocument->NodeInfoManager());
// Mark the parser as *not* broken by passing NS_OK
nsresult rv = mBuilder->MarkAsBroken(NS_OK);
NS_PRECONDITION(!mExecutor->HasStarted(),
"Tried to start parse without initializing the parser.");
mTreeBuilder->setScriptingEnabled(aScriptingEnabledForNoscriptParsing);
mTreeBuilder->setIsSrcdocDocument(aDocument->IsSrcdocDocument());
mBuilder->Start();
mTokenizer->start();
mExecutor->Start(); // Don't call WillBuildModel in fragment case
if (!aSourceBuffer.IsEmpty()) {
bool lastWasCR = false;
nsHtml5DependentUTF16Buffer buffer(aSourceBuffer);
@@ -112,25 +110,15 @@ nsHtml5StringParser::Tokenize(const nsAString& aSourceBuffer,
lastWasCR = false;
if (buffer.hasMore()) {
lastWasCR = mTokenizer->tokenizeBuffer(&buffer);
if (mTreeBuilder->HasScript()) {
// If we come here, we are in createContextualFragment() or in the
// upcoming document.parse(). It's unclear if it's really necessary
// to flush here, but let's do so for consistency with other flushes
// to avoid different code paths on the executor side.
mTreeBuilder->Flush(); // Move ops to the executor
mExecutor->FlushDocumentWrite(); // run the ops
if (NS_FAILED(rv = mBuilder->IsBroken())) {
break;
}
}
}
}
mTokenizer->eof();
mTreeBuilder->StreamEnded();
mTreeBuilder->Flush();
mExecutor->FlushDocumentWrite();
mTokenizer->end();
mExecutor->DropParserAndPerfHint();
mExecutor->DropHeldElements();
mTreeBuilder->DropHandles();
mBuilder->Finish();
mAtomTable.Clear();
mExecutor->Reset();
return rv;
}