mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1088635. r=smaug.
This commit is contained in:
parent
d252df7f19
commit
cfbff77873
@ -4016,7 +4016,7 @@ nsDocument::InsertChildAt(nsIContent* aKid, uint32_t aIndex,
|
||||
bool aNotify)
|
||||
{
|
||||
if (aKid->IsElement() && GetRootElement()) {
|
||||
NS_ERROR("Inserting element child when we already have one");
|
||||
NS_WARNING("Inserting root element when we already have one");
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
||||
* WillBuildModel to be called before the document has had its
|
||||
* script global object set.
|
||||
*/
|
||||
mExecutor->WillBuildModel(eDTDMode_unknown);
|
||||
rv = mExecutor->WillBuildModel(eDTDMode_unknown);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Return early if the parser has processed EOF
|
||||
@ -256,7 +257,7 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
||||
}
|
||||
mDocumentClosed = true;
|
||||
if (!mBlocked && !mInDocumentWrite) {
|
||||
ParseUntilBlocked();
|
||||
return ParseUntilBlocked();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -379,7 +380,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
||||
|
||||
if (mTreeBuilder->HasScript()) {
|
||||
mTreeBuilder->Flush(); // Move ops to the executor
|
||||
mExecutor->FlushDocumentWrite(); // run the ops
|
||||
rv = mExecutor->FlushDocumentWrite(); // run the ops
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Flushing tree ops can cause all sorts of things.
|
||||
// Return early if the parser got terminated.
|
||||
if (mExecutor->IsComplete()) {
|
||||
@ -438,7 +440,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
||||
"Buffer wasn't tokenized to completion?");
|
||||
// Scripting semantics require a forced tree builder flush here
|
||||
mTreeBuilder->Flush(); // Move ops to the executor
|
||||
mExecutor->FlushDocumentWrite(); // run the ops
|
||||
rv = mExecutor->FlushDocumentWrite(); // run the ops
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (stackBuffer.hasMore()) {
|
||||
// The buffer wasn't tokenized to completion. Tokenize the untokenized
|
||||
// content in order to preload stuff. This content will be retokenized
|
||||
@ -596,11 +599,13 @@ nsHtml5Parser::IsScriptCreated()
|
||||
/* End nsIParser */
|
||||
|
||||
// not from interface
|
||||
void
|
||||
nsresult
|
||||
nsHtml5Parser::ParseUntilBlocked()
|
||||
{
|
||||
if (mBlocked || mExecutor->IsComplete() || NS_FAILED(mExecutor->IsBroken())) {
|
||||
return;
|
||||
nsresult rv = mExecutor->IsBroken();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (mBlocked || mExecutor->IsComplete()) {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle.");
|
||||
NS_ASSERTION(!mInDocumentWrite,
|
||||
@ -613,7 +618,7 @@ nsHtml5Parser::ParseUntilBlocked()
|
||||
if (mFirstBuffer == mLastBuffer) {
|
||||
if (mExecutor->IsComplete()) {
|
||||
// something like cache manisfests stopped the parse in mid-flight
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
if (mDocumentClosed) {
|
||||
NS_ASSERTION(!GetStreamParser(),
|
||||
@ -622,8 +627,10 @@ nsHtml5Parser::ParseUntilBlocked()
|
||||
mTreeBuilder->StreamEnded();
|
||||
mTreeBuilder->Flush();
|
||||
mExecutor->FlushDocumentWrite();
|
||||
// The below call does memory cleanup, so call it even if the
|
||||
// parser has been marked as broken.
|
||||
mTokenizer->end();
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
// never release the last buffer.
|
||||
NS_ASSERTION(!mLastBuffer->getStart() && !mLastBuffer->getEnd(),
|
||||
@ -645,14 +652,14 @@ nsHtml5Parser::ParseUntilBlocked()
|
||||
NS_ASSERTION(mExecutor->IsInFlushLoop(),
|
||||
"How did we come here without being in the flush loop?");
|
||||
}
|
||||
return; // no more data for now but expecting more
|
||||
return NS_OK; // no more data for now but expecting more
|
||||
}
|
||||
mFirstBuffer = mFirstBuffer->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mBlocked || mExecutor->IsComplete()) {
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// now we have a non-empty buffer
|
||||
@ -669,10 +676,11 @@ nsHtml5Parser::ParseUntilBlocked()
|
||||
}
|
||||
if (mTreeBuilder->HasScript()) {
|
||||
mTreeBuilder->Flush();
|
||||
mExecutor->FlushDocumentWrite();
|
||||
nsresult rv = mExecutor->FlushDocumentWrite();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
if (mBlocked) {
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
@ -261,7 +261,7 @@ class nsHtml5Parser MOZ_FINAL : public nsIParser,
|
||||
/**
|
||||
* Parse until pending data is exhausted or a script blocks the parser
|
||||
*/
|
||||
void ParseUntilBlocked();
|
||||
nsresult ParseUntilBlocked();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -794,7 +794,7 @@ nsHtml5StreamParser::WriteStreamBytes(const uint8_t* aFromSegment,
|
||||
// NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE.
|
||||
if (!mLastBuffer) {
|
||||
NS_WARNING("mLastBuffer should not be null!");
|
||||
MarkAsBroken();
|
||||
MarkAsBroken(NS_ERROR_NULL_POINTER);
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mLastBuffer->getEnd() == NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE) {
|
||||
@ -900,7 +900,8 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
||||
* WillBuildModel to be called before the document has had its
|
||||
* script global object set.
|
||||
*/
|
||||
mExecutor->WillBuildModel(eDTDMode_unknown);
|
||||
rv = mExecutor->WillBuildModel(eDTDMode_unknown);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<nsHtml5OwningUTF16Buffer> newBuf =
|
||||
nsHtml5OwningUTF16Buffer::FalliblyCreate(
|
||||
@ -1009,8 +1010,9 @@ nsHtml5StreamParser::DoStopRequest()
|
||||
|
||||
if (!mUnicodeDecoder) {
|
||||
uint32_t writeCount;
|
||||
if (NS_FAILED(FinalizeSniffing(nullptr, 0, &writeCount, 0))) {
|
||||
MarkAsBroken();
|
||||
nsresult rv;
|
||||
if (NS_FAILED(rv = FinalizeSniffing(nullptr, 0, &writeCount, 0))) {
|
||||
MarkAsBroken(rv);
|
||||
return;
|
||||
}
|
||||
} else if (mFeedChardet) {
|
||||
@ -1082,7 +1084,7 @@ nsHtml5StreamParser::DoDataAvailable(const uint8_t* aBuffer, uint32_t aLength)
|
||||
rv = SniffStreamBytes(aBuffer, aLength, &writeCount);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
MarkAsBroken();
|
||||
MarkAsBroken(rv);
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(writeCount == aLength, "Wrong number of stream bytes written/sniffed.");
|
||||
@ -1668,13 +1670,13 @@ nsHtml5StreamParser::TimerFlush()
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5StreamParser::MarkAsBroken()
|
||||
nsHtml5StreamParser::MarkAsBroken(nsresult aRv)
|
||||
{
|
||||
NS_ASSERTION(IsParserThread(), "Wrong thread!");
|
||||
mTokenizerMutex.AssertCurrentThreadOwns();
|
||||
|
||||
Terminate();
|
||||
mTreeBuilder->MarkAsBroken();
|
||||
mTreeBuilder->MarkAsBroken(aRv);
|
||||
mozilla::DebugOnly<bool> hadOps = mTreeBuilder->Flush(false);
|
||||
NS_ASSERTION(hadOps, "Should have had the markAsBroken op!");
|
||||
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
|
||||
|
@ -217,7 +217,7 @@ class nsHtml5StreamParser : public nsICharsetDetectionObserver {
|
||||
}
|
||||
#endif
|
||||
|
||||
void MarkAsBroken();
|
||||
void MarkAsBroken(nsresult aRv);
|
||||
|
||||
/**
|
||||
* Marks the stream parser as interrupted. If you ever add calls to this
|
||||
|
@ -929,14 +929,14 @@ nsHtml5TreeBuilder::DropHandles()
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::MarkAsBroken()
|
||||
nsHtml5TreeBuilder::MarkAsBroken(nsresult aRv)
|
||||
{
|
||||
if (MOZ_UNLIKELY(mBuilder)) {
|
||||
MOZ_ASSERT_UNREACHABLE("Must not call this with builder.");
|
||||
return;
|
||||
}
|
||||
mOpQueue.Clear(); // Previous ops don't matter anymore
|
||||
mOpQueue.AppendElement()->Init(eTreeOpMarkAsBroken);
|
||||
mOpQueue.AppendElement()->Init(aRv);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -223,4 +223,4 @@
|
||||
|
||||
void errEndWithUnclosedElements(nsIAtom* aName);
|
||||
|
||||
void MarkAsBroken();
|
||||
void MarkAsBroken(nsresult aRv);
|
||||
|
@ -413,7 +413,11 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
|
||||
GetParser()->GetStreamParser();
|
||||
// Now parse content left in the document.write() buffer queue if any.
|
||||
// This may generate tree ops on its own or dequeue a speculation.
|
||||
GetParser()->ParseUntilBlocked();
|
||||
nsresult rv = GetParser()->ParseUntilBlocked();
|
||||
if (NS_FAILED(rv)) {
|
||||
MarkAsBroken(rv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mOpQueue.IsEmpty()) {
|
||||
@ -496,21 +500,24 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsHtml5TreeOpExecutor::FlushDocumentWrite()
|
||||
{
|
||||
nsresult rv = IsBroken();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
FlushSpeculativeLoads(); // Make sure speculative loads never start after the
|
||||
// corresponding normal loads for the same URLs.
|
||||
|
||||
if (MOZ_UNLIKELY(!mParser)) {
|
||||
// The parse has ended.
|
||||
mOpQueue.Clear(); // clear in order to be able to assert in destructor
|
||||
return;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mFlushState != eNotFlushing) {
|
||||
// XXX Can this happen? In case it can, let's avoid crashing.
|
||||
return;
|
||||
return rv;
|
||||
}
|
||||
|
||||
mFlushState = eInFlush;
|
||||
@ -543,7 +550,7 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite()
|
||||
}
|
||||
NS_ASSERTION(mFlushState == eInDocUpdate,
|
||||
"Tried to perform tree op outside update batch.");
|
||||
nsresult rv = iter->Perform(this, &scriptElement);
|
||||
rv = iter->Perform(this, &scriptElement);
|
||||
if (NS_FAILED(rv)) {
|
||||
MarkAsBroken(rv);
|
||||
break;
|
||||
@ -558,13 +565,14 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite()
|
||||
|
||||
if (MOZ_UNLIKELY(!mParser)) {
|
||||
// Ending the doc update caused a call to nsIParser::Terminate().
|
||||
return;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (scriptElement) {
|
||||
// must be tail call when mFlushState is eNotFlushing
|
||||
RunScript(scriptElement);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// copied from HTML content sink
|
||||
|
@ -178,7 +178,7 @@ class nsHtml5TreeOpExecutor MOZ_FINAL : public nsHtml5DocumentBuilder,
|
||||
|
||||
void RunFlushLoop();
|
||||
|
||||
void FlushDocumentWrite();
|
||||
nsresult FlushDocumentWrite();
|
||||
|
||||
void MaybeSuspend();
|
||||
|
||||
|
@ -197,6 +197,10 @@ nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
|
||||
nsIDocument* doc = aBuilder->GetDocument();
|
||||
uint32_t childCount = doc->GetChildCount();
|
||||
rv = doc->AppendChildTo(aNode, false);
|
||||
if (rv == NS_ERROR_DOM_HIERARCHY_REQUEST_ERR) {
|
||||
aNode->SetParserHasNotified();
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
aNode->SetParserHasNotified();
|
||||
nsNodeUtils::ContentInserted(doc, aNode, childCount);
|
||||
@ -726,8 +730,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpMarkAsBroken: {
|
||||
aBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_OK;
|
||||
return mOne.result;
|
||||
}
|
||||
case eTreeOpRunScript: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
|
@ -432,6 +432,15 @@ class nsHtml5TreeOperation {
|
||||
mFour.integer = aInt;
|
||||
}
|
||||
|
||||
inline void Init(nsresult aRv)
|
||||
{
|
||||
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
NS_PRECONDITION(NS_FAILED(aRv), "Initialized tree op with non-failure.");
|
||||
mOpCode = eTreeOpMarkAsBroken;
|
||||
mOne.result = aRv;
|
||||
}
|
||||
|
||||
inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass)
|
||||
{
|
||||
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
|
||||
@ -484,11 +493,12 @@ class nsHtml5TreeOperation {
|
||||
nsIAtom* atom;
|
||||
nsHtml5HtmlAttributes* attributes;
|
||||
nsHtml5DocumentMode mode;
|
||||
char16_t* unicharPtr;
|
||||
char16_t* unicharPtr;
|
||||
char* charPtr;
|
||||
nsHtml5TreeOperationStringPair* stringPair;
|
||||
nsAHtml5TreeBuilderState* state;
|
||||
int32_t integer;
|
||||
nsresult result;
|
||||
} mOne, mTwo, mThree, mFour;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user