Bug 482919 - Add speculative parsing to the HTML5 parser. r=bnewman.

This commit is contained in:
Henri Sivonen
2009-10-12 16:08:04 +03:00
parent 87b1f6516d
commit e5e8f90558
20 changed files with 934 additions and 215 deletions

View File

@@ -91,10 +91,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHtml5TreeOpExecutor, nsContent
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor()
: mHasProcessedBase(PR_FALSE)
, mReadingFromStage(PR_FALSE)
, mFlushTimer(do_CreateInstance("@mozilla.org/timer;1"))
: mFlushTimer(do_CreateInstance("@mozilla.org/timer;1"))
{
// zeroing operator new for everything else
}
nsHtml5TreeOpExecutor::~nsHtml5TreeOpExecutor()
@@ -124,9 +123,8 @@ nsHtml5TreeOpExecutor::WillParse()
NS_IMETHODIMP
nsHtml5TreeOpExecutor::DidBuildModel(PRBool aTerminated)
{
NS_PRECONDITION(mLifeCycle == PARSING,
NS_PRECONDITION(mStarted && mParser,
"Bad life cycle.");
mLifeCycle = TERMINATED;
// This is comes from nsXMLContentSink
DidBuildModelImpl(aTerminated);
mDocument->ScriptLoader()->RemoveObserver(this);
@@ -266,15 +264,13 @@ nsHtml5TreeOpExecutor::UpdateStyleSheet(nsIContent* aElement)
void
nsHtml5TreeOpExecutor::Flush()
{
nsRefPtr<nsHtml5TreeOpExecutor> kungFuDeathGrip(this); // avoid crashing near EOF
nsCOMPtr<nsIParser> parserKungFuDeathGrip(mParser);
if (mLifeCycle == TERMINATED) {
if (!mParser) {
mFlushTimer->Cancel();
return;
}
NS_ASSERTION(mParser, "mParser was nulled out but life cycle wasn't terminated.");
nsRefPtr<nsHtml5TreeOpExecutor> kungFuDeathGrip(this); // avoid crashing near EOF
nsCOMPtr<nsIParser> parserKungFuDeathGrip(mParser);
if (mReadingFromStage) {
mStage.RetrieveOperations(mOpQueue);
@@ -420,7 +416,7 @@ nsHtml5TreeOpExecutor::ExecuteScript()
NS_ASSERTION(mScriptElement, "No script to run");
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(mScriptElement);
if (mLifeCycle == TERMINATED) {
if (!mParser) {
NS_ASSERTION(sele->IsMalformed(), "Script wasn't marked as malformed.");
// We got here not because of an end tag but because the tree builder
// popped an incomplete script element on EOF. Returning here to avoid
@@ -442,11 +438,12 @@ nsHtml5TreeOpExecutor::ExecuteScript()
if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
mScriptElements.AppendObject(sele);
mParser->BlockParser();
} else if (mLifeCycle != TERMINATED) {
} else {
// This may have already happened if the script executed, but in case
// it didn't then remove the element so that it doesn't get stuck forever.
htmlDocument->ScriptExecuted(sele);
static_cast<nsHtml5Parser*> (mParser.get())->MaybePostContinueEvent();
// mParser may have been nulled out by now, but nsContentSink deals
ContinueInterruptedParsingAsync();
}
}
@@ -466,8 +463,8 @@ nsHtml5TreeOpExecutor::Init(nsIDocument* aDoc,
void
nsHtml5TreeOpExecutor::Start()
{
NS_PRECONDITION(mLifeCycle == NOT_STARTED, "Tried to start when already started.");
mLifeCycle = PARSING;
NS_PRECONDITION(!mStarted, "Tried to start when already started.");
mStarted = PR_TRUE;
mScriptElement = nsnull;
ScheduleTimer();
}
@@ -505,7 +502,7 @@ nsHtml5TreeOpExecutor::Reset() {
mHasProcessedBase = PR_FALSE;
mReadingFromStage = PR_FALSE;
mOpQueue.Clear();
mLifeCycle = NOT_STARTED;
mStarted = PR_FALSE;
mScriptElement = nsnull;
mCallDidBuildModel = PR_FALSE;
}