forked from mirrors/gecko-dev
Backed out changeset aa30bc1b369b (bug 1763076) for causing assertion failure in parser/html/nsHtml5TreeOpExecutor.cpp CLOSED TREE
This commit is contained in:
parent
e70200b735
commit
622b026960
16 changed files with 81 additions and 293 deletions
|
|
@ -19,11 +19,8 @@ class nsAHtml5TreeOpSink {
|
||||||
/**
|
/**
|
||||||
* Flush the operations from the tree operations from the argument
|
* Flush the operations from the tree operations from the argument
|
||||||
* queue into this sink unconditionally.
|
* queue into this sink unconditionally.
|
||||||
*
|
|
||||||
* Returns `true` on success and `false` on OOM.
|
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] virtual bool MoveOpsFrom(
|
virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) = 0;
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsAHtml5TreeOpSink_h */
|
#endif /* nsAHtml5TreeOpSink_h */
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "nsHtml5Highlighter.h"
|
#include "nsHtml5Highlighter.h"
|
||||||
#include "ErrorList.h"
|
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsHtml5AttributeName.h"
|
#include "nsHtml5AttributeName.h"
|
||||||
#include "nsHtml5Tokenizer.h"
|
#include "nsHtml5Tokenizer.h"
|
||||||
|
|
@ -463,7 +462,7 @@ int32_t nsHtml5Highlighter::Transition(int32_t aState, bool aReconsume,
|
||||||
return aState;
|
return aState;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool nsHtml5Highlighter::End() {
|
void nsHtml5Highlighter::End() {
|
||||||
switch (mState) {
|
switch (mState) {
|
||||||
case nsHtml5Tokenizer::COMMENT_END:
|
case nsHtml5Tokenizer::COMMENT_END:
|
||||||
case nsHtml5Tokenizer::COMMENT_END_BANG:
|
case nsHtml5Tokenizer::COMMENT_END_BANG:
|
||||||
|
|
@ -502,7 +501,7 @@ int32_t nsHtml5Highlighter::Transition(int32_t aState, bool aReconsume,
|
||||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||||
treeOp->Init(mozilla::AsVariant(opStreamEnded()));
|
treeOp->Init(mozilla::AsVariant(opStreamEnded()));
|
||||||
return FlushOps().isOk();
|
FlushOps();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer* aBuffer) {
|
void nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer* aBuffer) {
|
||||||
|
|
@ -619,19 +618,10 @@ void nsHtml5Highlighter::FlushCurrent() {
|
||||||
FlushChars();
|
FlushChars();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsHtml5Highlighter::ShouldFlushOps() {
|
bool nsHtml5Highlighter::FlushOps() {
|
||||||
// Arbitrary threshold that doesn't have an exact justification.
|
|
||||||
// The general idea is to flush much, much sooner than reaching
|
|
||||||
// the maximum size of `nsTArray`.
|
|
||||||
return mOpQueue.Length() > 100000;
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::Result<bool, nsresult> nsHtml5Highlighter::FlushOps() {
|
|
||||||
bool hasOps = !mOpQueue.IsEmpty();
|
bool hasOps = !mOpQueue.IsEmpty();
|
||||||
if (hasOps) {
|
if (hasOps) {
|
||||||
if (!mOpSink->MoveOpsFrom(mOpQueue)) {
|
mOpSink->MoveOpsFrom(mOpQueue);
|
||||||
return Err(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return hasOps;
|
return hasOps;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,8 @@ class nsHtml5Highlighter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report end of file.
|
* Report end of file.
|
||||||
*
|
|
||||||
* Returns `true` normally and `false` on OOM.
|
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool End();
|
void End();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current buffer being tokenized
|
* Set the current buffer being tokenized
|
||||||
|
|
@ -79,21 +77,12 @@ class nsHtml5Highlighter {
|
||||||
*/
|
*/
|
||||||
void DropBuffer(int32_t aPos);
|
void DropBuffer(int32_t aPos);
|
||||||
|
|
||||||
/**
|
|
||||||
* Query whether there are some many ops in the queue
|
|
||||||
* that they should be flushed now.
|
|
||||||
*
|
|
||||||
* @return true if FlushOps() should be called now
|
|
||||||
*/
|
|
||||||
bool ShouldFlushOps();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush the tree ops into the sink.
|
* Flush the tree ops into the sink.
|
||||||
*
|
*
|
||||||
* @return Ok(true) if there were ops to flush, Ok(false)
|
* @return true if there were ops to flush
|
||||||
* if there were no ops to flush and Err() on OOM.
|
|
||||||
*/
|
*/
|
||||||
mozilla::Result<bool, nsresult> FlushOps();
|
bool FlushOps();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linkify the current attribute value if the attribute name is one of
|
* Linkify the current attribute value if the attribute name is one of
|
||||||
|
|
|
||||||
|
|
@ -332,10 +332,7 @@ nsresult nsHtml5Parser::Parse(const nsAString& aSourceBuffer, void* aKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTreeBuilder->HasScript()) {
|
if (mTreeBuilder->HasScript()) {
|
||||||
auto r = mTreeBuilder->Flush(); // Move ops to the executor
|
mTreeBuilder->Flush(); // Move ops to the executor
|
||||||
if (r.isErr()) {
|
|
||||||
return executor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
rv = executor->FlushDocumentWrite(); // run the ops
|
rv = executor->FlushDocumentWrite(); // run the ops
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
// Flushing tree ops can cause all sorts of things.
|
// Flushing tree ops can cause all sorts of things.
|
||||||
|
|
@ -395,10 +392,7 @@ nsresult nsHtml5Parser::Parse(const nsAString& aSourceBuffer, void* aKey,
|
||||||
NS_ASSERTION(!stackBuffer.hasMore(),
|
NS_ASSERTION(!stackBuffer.hasMore(),
|
||||||
"Buffer wasn't tokenized to completion?");
|
"Buffer wasn't tokenized to completion?");
|
||||||
// Scripting semantics require a forced tree builder flush here
|
// Scripting semantics require a forced tree builder flush here
|
||||||
auto r = mTreeBuilder->Flush(); // Move ops to the executor
|
mTreeBuilder->Flush(); // Move ops to the executor
|
||||||
if (r.isErr()) {
|
|
||||||
return executor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
rv = executor->FlushDocumentWrite(); // run the ops
|
rv = executor->FlushDocumentWrite(); // run the ops
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else if (stackBuffer.hasMore()) {
|
} else if (stackBuffer.hasMore()) {
|
||||||
|
|
@ -448,10 +442,7 @@ nsresult nsHtml5Parser::Parse(const nsAString& aSourceBuffer, void* aKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto r = mDocWriteSpeculativeTreeBuilder->Flush();
|
mDocWriteSpeculativeTreeBuilder->Flush();
|
||||||
if (r.isErr()) {
|
|
||||||
return executor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
mDocWriteSpeculativeTreeBuilder->DropHandles();
|
mDocWriteSpeculativeTreeBuilder->DropHandles();
|
||||||
executor->FlushSpeculativeLoads();
|
executor->FlushSpeculativeLoads();
|
||||||
}
|
}
|
||||||
|
|
@ -557,10 +548,7 @@ nsresult nsHtml5Parser::ParseUntilBlocked() {
|
||||||
mTreeBuilder->StreamEnded();
|
mTreeBuilder->StreamEnded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto r = mTreeBuilder->Flush();
|
mTreeBuilder->Flush();
|
||||||
if (r.isErr()) {
|
|
||||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
mExecutor->FlushDocumentWrite();
|
mExecutor->FlushDocumentWrite();
|
||||||
// The below call does memory cleanup, so call it even if the
|
// The below call does memory cleanup, so call it even if the
|
||||||
// parser has been marked as broken.
|
// parser has been marked as broken.
|
||||||
|
|
@ -573,20 +561,14 @@ nsresult nsHtml5Parser::ParseUntilBlocked() {
|
||||||
if (GetStreamParser()) {
|
if (GetStreamParser()) {
|
||||||
if (mReturnToStreamParserPermitted &&
|
if (mReturnToStreamParserPermitted &&
|
||||||
!mExecutor->IsScriptExecuting()) {
|
!mExecutor->IsScriptExecuting()) {
|
||||||
auto r = mTreeBuilder->Flush();
|
mTreeBuilder->Flush();
|
||||||
if (r.isErr()) {
|
|
||||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
mReturnToStreamParserPermitted = false;
|
mReturnToStreamParserPermitted = false;
|
||||||
GetStreamParser()->ContinueAfterScriptsOrEncodingCommitment(
|
GetStreamParser()->ContinueAfterScriptsOrEncodingCommitment(
|
||||||
mTokenizer.get(), mTreeBuilder.get(), mLastWasCR);
|
mTokenizer.get(), mTreeBuilder.get(), mLastWasCR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Script-created parser
|
// Script-created parser
|
||||||
auto r = mTreeBuilder->Flush();
|
mTreeBuilder->Flush();
|
||||||
if (r.isErr()) {
|
|
||||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
// No need to flush the executor, because the executor is already
|
// No need to flush the executor, because the executor is already
|
||||||
// in a flush
|
// in a flush
|
||||||
NS_ASSERTION(mExecutor->IsInFlushLoop(),
|
NS_ASSERTION(mExecutor->IsInFlushLoop(),
|
||||||
|
|
@ -622,10 +604,7 @@ nsresult nsHtml5Parser::ParseUntilBlocked() {
|
||||||
mRootContextLineNumber = mTokenizer->getLineNumber();
|
mRootContextLineNumber = mTokenizer->getLineNumber();
|
||||||
}
|
}
|
||||||
if (mTreeBuilder->HasScript()) {
|
if (mTreeBuilder->HasScript()) {
|
||||||
auto r = mTreeBuilder->Flush();
|
mTreeBuilder->Flush();
|
||||||
if (r.isErr()) {
|
|
||||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
rv = mExecutor->FlushDocumentWrite();
|
rv = mExecutor->FlushDocumentWrite();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,10 @@ nsHtml5Speculation::~nsHtml5Speculation() {
|
||||||
MOZ_COUNT_DTOR(nsHtml5Speculation);
|
MOZ_COUNT_DTOR(nsHtml5Speculation);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool nsHtml5Speculation::MoveOpsFrom(
|
void nsHtml5Speculation::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) {
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue) {
|
mOpQueue.AppendElements(std::move(aOpQueue));
|
||||||
return !!mOpQueue.AppendElements(std::move(aOpQueue), mozilla::fallible_t());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool nsHtml5Speculation::FlushToSink(nsAHtml5TreeOpSink* aSink) {
|
void nsHtml5Speculation::FlushToSink(nsAHtml5TreeOpSink* aSink) {
|
||||||
return aSink->MoveOpsFrom(mOpQueue);
|
aSink->MoveOpsFrom(mOpQueue);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,9 @@ class nsHtml5Speculation final : public nsAHtml5TreeOpSink {
|
||||||
* Flush the operations from the tree operations from the argument
|
* Flush the operations from the tree operations from the argument
|
||||||
* queue unconditionally.
|
* queue unconditionally.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] virtual bool MoveOpsFrom(
|
virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
|
|
||||||
|
|
||||||
[[nodiscard]] bool FlushToSink(nsAHtml5TreeOpSink* aSink);
|
void FlushToSink(nsAHtml5TreeOpSink* aSink);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "ErrorList.h"
|
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
#include "js/GCAPI.h"
|
#include "js/GCAPI.h"
|
||||||
#include "mozilla/ArrayIterator.h"
|
#include "mozilla/ArrayIterator.h"
|
||||||
|
|
@ -776,15 +775,9 @@ nsresult nsHtml5StreamParser::SniffStreamBytes(Span<const uint8_t> aFromSegment,
|
||||||
MOZ_ASSERT(mLookingForMetaCharset);
|
MOZ_ASSERT(mLookingForMetaCharset);
|
||||||
|
|
||||||
if (mMode == VIEW_SOURCE_HTML) {
|
if (mMode == VIEW_SOURCE_HTML) {
|
||||||
auto r = mTokenizer->FlushViewSource();
|
mTokenizer->FlushViewSource();
|
||||||
if (r.isErr()) {
|
|
||||||
return r.unwrapErr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto r = mTreeBuilder->Flush();
|
|
||||||
if (r.isErr()) {
|
|
||||||
return r.unwrapErr();
|
|
||||||
}
|
}
|
||||||
|
mTreeBuilder->Flush();
|
||||||
// Encoding committer flushes the ops on the main thread.
|
// Encoding committer flushes the ops on the main thread.
|
||||||
|
|
||||||
mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
|
mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
|
||||||
|
|
@ -930,16 +923,10 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
|
||||||
mCharsetSource = source;
|
mCharsetSource = source;
|
||||||
if (encoding != mEncoding) {
|
if (encoding != mEncoding) {
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
nsresult rv = ReDecodeLocalFile();
|
ReDecodeLocalFile();
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(mEncoding == UTF_8_ENCODING);
|
MOZ_ASSERT(mEncoding == UTF_8_ENCODING);
|
||||||
nsresult rv = CommitLocalFileToEncoding();
|
CommitLocalFileToEncoding();
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
@ -947,7 +934,7 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] nsresult nsHtml5StreamParser::ReDecodeLocalFile() {
|
void nsHtml5StreamParser::ReDecodeLocalFile() {
|
||||||
MOZ_ASSERT(mDecodingLocalFileWithoutTokenizing && !mLookingForMetaCharset);
|
MOZ_ASSERT(mDecodingLocalFileWithoutTokenizing && !mLookingForMetaCharset);
|
||||||
MOZ_ASSERT(mFirstBufferOfMetaScan);
|
MOZ_ASSERT(mFirstBufferOfMetaScan);
|
||||||
MOZ_ASSERT(mCharsetSource == kCharsetFromFinalAutoDetectionFile ||
|
MOZ_ASSERT(mCharsetSource == kCharsetFromFinalAutoDetectionFile ||
|
||||||
|
|
@ -981,19 +968,12 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMode == VIEW_SOURCE_HTML) {
|
if (mMode == VIEW_SOURCE_HTML) {
|
||||||
auto r = mTokenizer->FlushViewSource();
|
mTokenizer->FlushViewSource();
|
||||||
if (r.isErr()) {
|
|
||||||
return r.unwrapErr();
|
|
||||||
}
|
}
|
||||||
}
|
mTreeBuilder->Flush();
|
||||||
auto r = mTreeBuilder->Flush();
|
|
||||||
if (r.isErr()) {
|
|
||||||
return r.unwrapErr();
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] nsresult nsHtml5StreamParser::CommitLocalFileToEncoding() {
|
void nsHtml5StreamParser::CommitLocalFileToEncoding() {
|
||||||
MOZ_ASSERT(mDecodingLocalFileWithoutTokenizing && !mLookingForMetaCharset);
|
MOZ_ASSERT(mDecodingLocalFileWithoutTokenizing && !mLookingForMetaCharset);
|
||||||
MOZ_ASSERT(mFirstBufferOfMetaScan);
|
MOZ_ASSERT(mFirstBufferOfMetaScan);
|
||||||
mDecodingLocalFileWithoutTokenizing = false;
|
mDecodingLocalFileWithoutTokenizing = false;
|
||||||
|
|
@ -1019,16 +999,9 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
|
||||||
mForceAutoDetection = false; // To stop feeding the detector
|
mForceAutoDetection = false; // To stop feeding the detector
|
||||||
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, true);
|
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, true);
|
||||||
if (mMode == VIEW_SOURCE_HTML) {
|
if (mMode == VIEW_SOURCE_HTML) {
|
||||||
auto r = mTokenizer->FlushViewSource();
|
mTokenizer->FlushViewSource();
|
||||||
if (r.isErr()) {
|
|
||||||
return r.unwrapErr();
|
|
||||||
}
|
}
|
||||||
}
|
mTreeBuilder->Flush();
|
||||||
auto r = mTreeBuilder->Flush();
|
|
||||||
if (r.isErr()) {
|
|
||||||
return r.unwrapErr();
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MaybeRunCollector : public Runnable {
|
class MaybeRunCollector : public Runnable {
|
||||||
|
|
@ -1136,10 +1109,7 @@ nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
||||||
mTemplatePushedOrHeadPopped); // Needed to force 1024-byte sniffing
|
mTemplatePushedOrHeadPopped); // Needed to force 1024-byte sniffing
|
||||||
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
||||||
// can find them.
|
// can find them.
|
||||||
auto r = mTreeBuilder->Flush();
|
mTreeBuilder->Flush();
|
||||||
if (r.isErr()) {
|
|
||||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
} else if (mMode == VIEW_SOURCE_PLAIN) {
|
} else if (mMode == VIEW_SOURCE_PLAIN) {
|
||||||
nsAutoString viewSourceTitle;
|
nsAutoString viewSourceTitle;
|
||||||
CopyUTF8toUTF16(mViewSourceTitle, viewSourceTitle);
|
CopyUTF8toUTF16(mViewSourceTitle, viewSourceTitle);
|
||||||
|
|
@ -1150,10 +1120,7 @@ nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
||||||
mTemplatePushedOrHeadPopped); // Needed to force 1024-byte sniffing
|
mTemplatePushedOrHeadPopped); // Needed to force 1024-byte sniffing
|
||||||
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
||||||
// can find them.
|
// can find them.
|
||||||
auto r = mTreeBuilder->Flush();
|
mTreeBuilder->Flush();
|
||||||
if (r.isErr()) {
|
|
||||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
} else if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
} else if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||||
// Generate and flush the View Source document up to and including the
|
// Generate and flush the View Source document up to and including the
|
||||||
// pre element start.
|
// pre element start.
|
||||||
|
|
@ -1163,10 +1130,7 @@ nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
||||||
}
|
}
|
||||||
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
||||||
// can find them.
|
// can find them.
|
||||||
auto r = mTokenizer->FlushViewSource();
|
mTokenizer->FlushViewSource();
|
||||||
if (r.isErr()) {
|
|
||||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1292,11 +1256,7 @@ void nsHtml5StreamParser::DoStopRequest() {
|
||||||
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, false);
|
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, false);
|
||||||
|
|
||||||
for (auto&& buffer : mBufferedBytes) {
|
for (auto&& buffer : mBufferedBytes) {
|
||||||
nsresult rv = WriteStreamBytes(buffer);
|
Unused << WriteStreamBytes(buffer);
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
MarkAsBroken(rv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (!mUnicodeDecoder) {
|
} else if (!mUnicodeDecoder) {
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
@ -1356,20 +1316,12 @@ void nsHtml5StreamParser::DoStopRequest() {
|
||||||
mCharsetSource = source;
|
mCharsetSource = source;
|
||||||
if (encoding != mEncoding) {
|
if (encoding != mEncoding) {
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
nsresult rv = ReDecodeLocalFile();
|
ReDecodeLocalFile();
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
MarkAsBroken(rv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DoStopRequest();
|
DoStopRequest();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(mEncoding == UTF_8_ENCODING);
|
MOZ_ASSERT(mEncoding == UTF_8_ENCODING);
|
||||||
nsresult rv = CommitLocalFileToEncoding();
|
CommitLocalFileToEncoding();
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
MarkAsBroken(rv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1781,23 +1733,6 @@ void nsHtml5StreamParser::PostLoadFlusher() {
|
||||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||||
NS_WARNING("failed to dispatch load flush event");
|
NS_WARNING("failed to dispatch load flush event");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) &&
|
|
||||||
mTokenizer->ShouldFlushViewSource()) {
|
|
||||||
auto r = mTreeBuilder->Flush(); // delete useless ops
|
|
||||||
MOZ_ASSERT(r.isOk(), "Should have null sink with View Source");
|
|
||||||
r = mTokenizer->FlushViewSource();
|
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (r.unwrap()) {
|
|
||||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
|
||||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
|
||||||
NS_WARNING("failed to dispatch executor flush event");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer() {
|
void nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer() {
|
||||||
|
|
@ -1812,15 +1747,9 @@ void nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer() {
|
||||||
mFlushTimerArmed = false;
|
mFlushTimerArmed = false;
|
||||||
}
|
}
|
||||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||||
auto r = mTokenizer->FlushViewSource();
|
mTokenizer->FlushViewSource();
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto r = mTreeBuilder->Flush();
|
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
}
|
}
|
||||||
|
mTreeBuilder->Flush();
|
||||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||||
NS_WARNING("failed to dispatch executor flush event");
|
NS_WARNING("failed to dispatch executor flush event");
|
||||||
|
|
@ -2235,17 +2164,9 @@ bool nsHtml5StreamParser::ProcessLookingForMetaCharset(bool aEof) {
|
||||||
mCharsetSource = mEncodingSwitchSource;
|
mCharsetSource = mEncodingSwitchSource;
|
||||||
|
|
||||||
if (mMode == VIEW_SOURCE_HTML) {
|
if (mMode == VIEW_SOURCE_HTML) {
|
||||||
auto r = mTokenizer->FlushViewSource();
|
mTokenizer->FlushViewSource();
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto r = mTreeBuilder->Flush();
|
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
mTreeBuilder->Flush();
|
||||||
|
|
||||||
if (mEncoding != needsEncodingSwitchTo) {
|
if (mEncoding != needsEncodingSwitchTo) {
|
||||||
// Speculation failed
|
// Speculation failed
|
||||||
|
|
@ -2284,11 +2205,7 @@ bool nsHtml5StreamParser::ProcessLookingForMetaCharset(bool aEof) {
|
||||||
"Must have set mLookingForMetaCharset to false to report data "
|
"Must have set mLookingForMetaCharset to false to report data "
|
||||||
"to dev tools below");
|
"to dev tools below");
|
||||||
for (auto&& buffer : mBufferedBytes) {
|
for (auto&& buffer : mBufferedBytes) {
|
||||||
nsresult rv = WriteStreamBytes(buffer);
|
WriteStreamBytes(buffer);
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
MarkAsBroken(rv);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!mLookingForMetaCharset && !mDecodingLocalFileWithoutTokenizing) {
|
} else if (!mLookingForMetaCharset && !mDecodingLocalFileWithoutTokenizing) {
|
||||||
|
|
@ -2313,17 +2230,9 @@ bool nsHtml5StreamParser::ProcessLookingForMetaCharset(bool aEof) {
|
||||||
mBufferedBytes.Clear();
|
mBufferedBytes.Clear();
|
||||||
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, true);
|
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, true);
|
||||||
if (mMode == VIEW_SOURCE_HTML) {
|
if (mMode == VIEW_SOURCE_HTML) {
|
||||||
auto r = mTokenizer->FlushViewSource();
|
mTokenizer->FlushViewSource();
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto r = mTreeBuilder->Flush();
|
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
mTreeBuilder->Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rewound;
|
return rewound;
|
||||||
|
|
@ -2446,9 +2355,7 @@ void nsHtml5StreamParser::ParseAvailableData() {
|
||||||
} else {
|
} else {
|
||||||
mTreeBuilder->StreamEnded();
|
mTreeBuilder->StreamEnded();
|
||||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||||
if (!mTokenizer->EndViewSource()) {
|
mTokenizer->EndViewSource();
|
||||||
MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2489,17 +2396,9 @@ void nsHtml5StreamParser::ParseAvailableData() {
|
||||||
speculation->GetStartLineNumber());
|
speculation->GetStartLineNumber());
|
||||||
if (mLookingForMetaCharset) {
|
if (mLookingForMetaCharset) {
|
||||||
if (mMode == VIEW_SOURCE_HTML) {
|
if (mMode == VIEW_SOURCE_HTML) {
|
||||||
auto r = mTokenizer->FlushViewSource();
|
mTokenizer->FlushViewSource();
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto r = mTreeBuilder->Flush();
|
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
mTreeBuilder->Flush();
|
||||||
} else {
|
} else {
|
||||||
FlushTreeOpsAndDisarmTimer();
|
FlushTreeOpsAndDisarmTimer();
|
||||||
}
|
}
|
||||||
|
|
@ -2559,10 +2458,7 @@ void nsHtml5StreamParser::ContinueAfterScriptsOrEncodingCommitment(
|
||||||
// XML View Source never needs this kind of encoding commitment.
|
// XML View Source never needs this kind of encoding commitment.
|
||||||
// We need to take the ops here so that they end up in the queue before
|
// We need to take the ops here so that they end up in the queue before
|
||||||
// the ops that we take from a speculation later in this method.
|
// the ops that we take from a speculation later in this method.
|
||||||
if (!mExecutor->TakeOpsFromStage()) {
|
mExecutor->TakeOpsFromStage();
|
||||||
mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
mExecutor->AssertStageEmpty();
|
mExecutor->AssertStageEmpty();
|
||||||
|
|
@ -2599,10 +2495,7 @@ void nsHtml5StreamParser::ContinueAfterScriptsOrEncodingCommitment(
|
||||||
if (mSpeculations.Length() > 1) {
|
if (mSpeculations.Length() > 1) {
|
||||||
// the first speculation isn't the current speculation, so there's
|
// the first speculation isn't the current speculation, so there's
|
||||||
// no need to bother the parser thread.
|
// no need to bother the parser thread.
|
||||||
if (!speculation->FlushToSink(mExecutor)) {
|
speculation->FlushToSink(mExecutor);
|
||||||
mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(!mExecutor->IsScriptExecuting(),
|
MOZ_ASSERT(!mExecutor->IsScriptExecuting(),
|
||||||
"ParseUntilBlocked() was supposed to ensure we don't come "
|
"ParseUntilBlocked() was supposed to ensure we don't come "
|
||||||
"here when scripts are executing.");
|
"here when scripts are executing.");
|
||||||
|
|
@ -2677,10 +2570,7 @@ void nsHtml5StreamParser::ContinueAfterScriptsOrEncodingCommitment(
|
||||||
} else {
|
} else {
|
||||||
// We've got a successful speculation and at least a moment ago it was
|
// We've got a successful speculation and at least a moment ago it was
|
||||||
// the current speculation
|
// the current speculation
|
||||||
if (!mSpeculations.ElementAt(0)->FlushToSink(mExecutor)) {
|
mSpeculations.ElementAt(0)->FlushToSink(mExecutor);
|
||||||
mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(!mExecutor->IsScriptExecuting(),
|
MOZ_ASSERT(!mExecutor->IsScriptExecuting(),
|
||||||
"ParseUntilBlocked() was supposed to ensure we don't come "
|
"ParseUntilBlocked() was supposed to ensure we don't come "
|
||||||
"here when scripts are executing.");
|
"here when scripts are executing.");
|
||||||
|
|
@ -2699,11 +2589,7 @@ void nsHtml5StreamParser::ContinueAfterScriptsOrEncodingCommitment(
|
||||||
// any pending ops straight to the executor, because otherwise
|
// any pending ops straight to the executor, because otherwise
|
||||||
// they remain unflushed until we get more data from the network.
|
// they remain unflushed until we get more data from the network.
|
||||||
mTreeBuilder->SetOpSink(mExecutor);
|
mTreeBuilder->SetOpSink(mExecutor);
|
||||||
auto r = mTreeBuilder->Flush(true);
|
mTreeBuilder->Flush(true);
|
||||||
if (r.isErr()) {
|
|
||||||
mExecutor->MarkAsBroken(r.unwrapErr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mTreeBuilder->SetOpSink(mExecutor->GetStage());
|
mTreeBuilder->SetOpSink(mExecutor->GetStage());
|
||||||
}
|
}
|
||||||
mExecutor->StartReadingFromStage();
|
mExecutor->StartReadingFromStage();
|
||||||
|
|
@ -2799,17 +2685,8 @@ void nsHtml5StreamParser::TimerFlush() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||||
auto r = mTreeBuilder->Flush(); // delete useless ops
|
mTreeBuilder->Flush(); // delete useless ops
|
||||||
if (r.isErr()) {
|
if (mTokenizer->FlushViewSource()) {
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r = mTokenizer->FlushViewSource();
|
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (r.unwrap()) {
|
|
||||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||||
NS_WARNING("failed to dispatch executor flush event");
|
NS_WARNING("failed to dispatch executor flush event");
|
||||||
|
|
@ -2818,12 +2695,7 @@ void nsHtml5StreamParser::TimerFlush() {
|
||||||
} else {
|
} else {
|
||||||
// we aren't speculating and we don't know when new data is
|
// we aren't speculating and we don't know when new data is
|
||||||
// going to arrive. Send data to the main thread.
|
// going to arrive. Send data to the main thread.
|
||||||
auto r = mTreeBuilder->Flush(true);
|
if (mTreeBuilder->Flush(true)) {
|
||||||
if (r.isErr()) {
|
|
||||||
MarkAsBroken(r.unwrapErr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (r.unwrap()) {
|
|
||||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||||
NS_WARNING("failed to dispatch executor flush event");
|
NS_WARNING("failed to dispatch executor flush event");
|
||||||
|
|
@ -2838,12 +2710,8 @@ void nsHtml5StreamParser::MarkAsBroken(nsresult aRv) {
|
||||||
|
|
||||||
Terminate();
|
Terminate();
|
||||||
mTreeBuilder->MarkAsBroken(aRv);
|
mTreeBuilder->MarkAsBroken(aRv);
|
||||||
auto r = mTreeBuilder->Flush(false);
|
mozilla::DebugOnly<bool> hadOps = mTreeBuilder->Flush(false);
|
||||||
if (r.isOk()) {
|
MOZ_ASSERT(hadOps, "Should have had the markAsBroken op!");
|
||||||
MOZ_ASSERT(r.unwrap(), "Should have had the markAsBroken op!");
|
|
||||||
} else {
|
|
||||||
MOZ_CRASH("OOM prevents propagation of OOM state");
|
|
||||||
}
|
|
||||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||||
NS_WARNING("failed to dispatch executor flush event");
|
NS_WARNING("failed to dispatch executor flush event");
|
||||||
|
|
|
||||||
|
|
@ -412,13 +412,13 @@ class nsHtml5StreamParser final : public nsISupports {
|
||||||
* to UTF-8 as the non-speculative encoding and start processing
|
* to UTF-8 as the non-speculative encoding and start processing
|
||||||
* the decoded data.
|
* the decoded data.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] nsresult CommitLocalFileToEncoding();
|
void CommitLocalFileToEncoding();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When speculatively decoding from file: URL as UTF-8, redecode
|
* When speculatively decoding from file: URL as UTF-8, redecode
|
||||||
* using fallback and then continue normally with the fallback.
|
* using fallback and then continue normally with the fallback.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] nsresult ReDecodeLocalFile() REQUIRES(mTokenizerMutex);
|
void ReDecodeLocalFile() REQUIRES(mTokenizerMutex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Potentially guess the encoding using mozilla::EncodingDetector.
|
* Potentially guess the encoding using mozilla::EncodingDetector.
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,7 @@ void nsHtml5Tokenizer::EnableViewSource(nsHtml5Highlighter* aHighlighter) {
|
||||||
mViewSource = WrapUnique(aHighlighter);
|
mViewSource = WrapUnique(aHighlighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsHtml5Tokenizer::ShouldFlushViewSource() {
|
bool nsHtml5Tokenizer::FlushViewSource() { return mViewSource->FlushOps(); }
|
||||||
return mViewSource->ShouldFlushOps();
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::Result<bool, nsresult> nsHtml5Tokenizer::FlushViewSource() {
|
|
||||||
return mViewSource->FlushOps();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsHtml5Tokenizer::StartViewSource(const nsAutoString& aTitle) {
|
void nsHtml5Tokenizer::StartViewSource(const nsAutoString& aTitle) {
|
||||||
mViewSource->Start(aTitle);
|
mViewSource->Start(aTitle);
|
||||||
|
|
@ -98,9 +92,7 @@ void nsHtml5Tokenizer::StartViewSourceCharacters() {
|
||||||
mViewSource->StartCharacters();
|
mViewSource->StartCharacters();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool nsHtml5Tokenizer::EndViewSource() {
|
void nsHtml5Tokenizer::EndViewSource() { mViewSource->End(); }
|
||||||
return mViewSource->End();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsHtml5Tokenizer::SetViewSourceOpSink(nsAHtml5TreeOpSink* aOpSink) {
|
void nsHtml5Tokenizer::SetViewSourceOpSink(nsAHtml5TreeOpSink* aOpSink) {
|
||||||
mViewSource->SetOpSink(aOpSink);
|
mViewSource->SetOpSink(aOpSink);
|
||||||
|
|
|
||||||
|
|
@ -34,15 +34,13 @@ void StartPlainText();
|
||||||
|
|
||||||
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
|
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
|
||||||
|
|
||||||
bool ShouldFlushViewSource();
|
bool FlushViewSource();
|
||||||
|
|
||||||
mozilla::Result<bool, nsresult> FlushViewSource();
|
|
||||||
|
|
||||||
void StartViewSource(const nsAutoString& aTitle);
|
void StartViewSource(const nsAutoString& aTitle);
|
||||||
|
|
||||||
void StartViewSourceCharacters();
|
void StartViewSourceCharacters();
|
||||||
|
|
||||||
[[nodiscard]] bool EndViewSource();
|
void EndViewSource();
|
||||||
|
|
||||||
void RewindViewSource();
|
void RewindViewSource();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "ErrorList.h"
|
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "mozilla/CheckedInt.h"
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
|
|
@ -1202,7 +1201,7 @@ bool nsHtml5TreeBuilder::HasScript() {
|
||||||
return mOpQueue.ElementAt(len - 1).IsRunScript();
|
return mOpQueue.ElementAt(len - 1).IsRunScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::Result<bool, nsresult> nsHtml5TreeBuilder::Flush(bool aDiscretionary) {
|
bool nsHtml5TreeBuilder::Flush(bool aDiscretionary) {
|
||||||
if (MOZ_UNLIKELY(mBuilder)) {
|
if (MOZ_UNLIKELY(mBuilder)) {
|
||||||
MOZ_ASSERT_UNREACHABLE("Must never flush with builder.");
|
MOZ_ASSERT_UNREACHABLE("Must never flush with builder.");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1231,9 +1230,7 @@ mozilla::Result<bool, nsresult> nsHtml5TreeBuilder::Flush(bool aDiscretionary) {
|
||||||
"Tree builder is broken but the op in queue is not marked "
|
"Tree builder is broken but the op in queue is not marked "
|
||||||
"as broken.");
|
"as broken.");
|
||||||
}
|
}
|
||||||
if (!mOpSink->MoveOpsFrom(mOpQueue)) {
|
mOpSink->MoveOpsFrom(mOpQueue);
|
||||||
return Err(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return hasOps;
|
return hasOps;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,12 +110,7 @@ void SetOpSink(nsAHtml5TreeOpSink* aOpSink) { mOpSink = aOpSink; }
|
||||||
|
|
||||||
void ClearOps() { mOpQueue.Clear(); }
|
void ClearOps() { mOpQueue.Clear(); }
|
||||||
|
|
||||||
/**
|
bool Flush(bool aDiscretionary = false);
|
||||||
* Flushes tree ops.
|
|
||||||
* @return Ok(true) if there were ops to flush, Ok(false)
|
|
||||||
* if there were no ops to flush and Err() on OOM.
|
|
||||||
*/
|
|
||||||
mozilla::Result<bool, nsresult> Flush(bool aDiscretionary = false);
|
|
||||||
|
|
||||||
void FlushLoads();
|
void FlushLoads();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
#include "mozilla/StaticPrefs_view_source.h"
|
#include "mozilla/StaticPrefs_view_source.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
#include "mozilla/css/Loader.h"
|
#include "mozilla/css/Loader.h"
|
||||||
#include "mozilla/fallible.h"
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsDocShell.h"
|
#include "nsDocShell.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
|
|
@ -141,8 +140,7 @@ nsHtml5TreeOpExecutor::~nsHtml5TreeOpExecutor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(NS_FAILED(mBroken) || mOpQueue.IsEmpty(),
|
NS_ASSERTION(mOpQueue.IsEmpty(), "Somehow there's stuff in the op queue.");
|
||||||
"Somehow there's stuff in the op queue.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIContentSink
|
// nsIContentSink
|
||||||
|
|
@ -611,12 +609,7 @@ void nsHtml5TreeOpExecutor::RunFlushLoop() {
|
||||||
nsTArray<nsHtml5SpeculativeLoad> speculativeLoadQueue;
|
nsTArray<nsHtml5SpeculativeLoad> speculativeLoadQueue;
|
||||||
MOZ_RELEASE_ASSERT(mFlushState == eNotFlushing,
|
MOZ_RELEASE_ASSERT(mFlushState == eNotFlushing,
|
||||||
"mOpQueue modified during flush.");
|
"mOpQueue modified during flush.");
|
||||||
if (!mStage.MoveOpsAndSpeculativeLoadsTo(mOpQueue,
|
mStage.MoveOpsAndSpeculativeLoadsTo(mOpQueue, speculativeLoadQueue);
|
||||||
speculativeLoadQueue)) {
|
|
||||||
MarkAsBroken(nsresult::NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure speculative loads never start after the corresponding
|
// Make sure speculative loads never start after the corresponding
|
||||||
// normal loads for the same URLs.
|
// normal loads for the same URLs.
|
||||||
nsHtml5SpeculativeLoad* start = speculativeLoadQueue.Elements();
|
nsHtml5SpeculativeLoad* start = speculativeLoadQueue.Elements();
|
||||||
|
|
@ -850,9 +843,7 @@ void nsHtml5TreeOpExecutor::CommitToInternalEncoding() {
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool nsHtml5TreeOpExecutor::TakeOpsFromStage() {
|
void nsHtml5TreeOpExecutor::TakeOpsFromStage() { mStage.MoveOpsTo(mOpQueue); }
|
||||||
return mStage.MoveOpsTo(mOpQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copied from HTML content sink
|
// copied from HTML content sink
|
||||||
bool nsHtml5TreeOpExecutor::IsScriptEnabled() {
|
bool nsHtml5TreeOpExecutor::IsScriptEnabled() {
|
||||||
|
|
@ -1046,11 +1037,11 @@ nsHtml5Parser* nsHtml5TreeOpExecutor::GetParser() {
|
||||||
return static_cast<nsHtml5Parser*>(mParser.get());
|
return static_cast<nsHtml5Parser*>(mParser.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool nsHtml5TreeOpExecutor::MoveOpsFrom(
|
void nsHtml5TreeOpExecutor::MoveOpsFrom(
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue) {
|
nsTArray<nsHtml5TreeOperation>& aOpQueue) {
|
||||||
MOZ_RELEASE_ASSERT(mFlushState == eNotFlushing,
|
MOZ_RELEASE_ASSERT(mFlushState == eNotFlushing,
|
||||||
"Ops added to mOpQueue during tree op execution.");
|
"Ops added to mOpQueue during tree op execution.");
|
||||||
return !!mOpQueue.AppendElements(std::move(aOpQueue), mozilla::fallible_t());
|
mOpQueue.AppendElements(std::move(aOpQueue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsHtml5TreeOpExecutor::ClearOpQueue() {
|
void nsHtml5TreeOpExecutor::ClearOpQueue() {
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ class nsHtml5TreeOpExecutor final
|
||||||
|
|
||||||
void CommitToInternalEncoding();
|
void CommitToInternalEncoding();
|
||||||
|
|
||||||
[[nodiscard]] bool TakeOpsFromStage();
|
void TakeOpsFromStage();
|
||||||
|
|
||||||
void MaybeSuspend();
|
void MaybeSuspend();
|
||||||
|
|
||||||
|
|
@ -220,8 +220,7 @@ class nsHtml5TreeOpExecutor final
|
||||||
* Flush the operations from the tree operations from the argument
|
* Flush the operations from the tree operations from the argument
|
||||||
* queue unconditionally. (This is for the main thread case.)
|
* queue unconditionally. (This is for the main thread case.)
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] virtual bool MoveOpsFrom(
|
virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
|
|
||||||
|
|
||||||
void ClearOpQueue();
|
void ClearOpQueue();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,26 +10,22 @@ nsHtml5TreeOpStage::nsHtml5TreeOpStage() : mMutex("nsHtml5TreeOpStage mutex") {}
|
||||||
|
|
||||||
nsHtml5TreeOpStage::~nsHtml5TreeOpStage() {}
|
nsHtml5TreeOpStage::~nsHtml5TreeOpStage() {}
|
||||||
|
|
||||||
bool nsHtml5TreeOpStage::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) {
|
void nsHtml5TreeOpStage::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) {
|
||||||
mozilla::MutexAutoLock autoLock(mMutex);
|
mozilla::MutexAutoLock autoLock(mMutex);
|
||||||
return !!mOpQueue.AppendElements(std::move(aOpQueue), mozilla::fallible_t());
|
mOpQueue.AppendElements(std::move(aOpQueue));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool nsHtml5TreeOpStage::MoveOpsAndSpeculativeLoadsTo(
|
void nsHtml5TreeOpStage::MoveOpsAndSpeculativeLoadsTo(
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue,
|
nsTArray<nsHtml5TreeOperation>& aOpQueue,
|
||||||
nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue) {
|
nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue) {
|
||||||
mozilla::MutexAutoLock autoLock(mMutex);
|
mozilla::MutexAutoLock autoLock(mMutex);
|
||||||
if (!aOpQueue.AppendElements(std::move(mOpQueue), mozilla::fallible_t())) {
|
aOpQueue.AppendElements(std::move(mOpQueue));
|
||||||
return false;
|
|
||||||
};
|
|
||||||
aSpeculativeLoadQueue.AppendElements(std::move(mSpeculativeLoadQueue));
|
aSpeculativeLoadQueue.AppendElements(std::move(mSpeculativeLoadQueue));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool nsHtml5TreeOpStage::MoveOpsTo(
|
void nsHtml5TreeOpStage::MoveOpsTo(nsTArray<nsHtml5TreeOperation>& aOpQueue) {
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue) {
|
|
||||||
mozilla::MutexAutoLock autoLock(mMutex);
|
mozilla::MutexAutoLock autoLock(mMutex);
|
||||||
return !!aOpQueue.AppendElements(std::move(mOpQueue), mozilla::fallible_t());
|
aOpQueue.AppendElements(std::move(mOpQueue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsHtml5TreeOpStage::MoveSpeculativeLoadsFrom(
|
void nsHtml5TreeOpStage::MoveSpeculativeLoadsFrom(
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,17 @@ class nsHtml5TreeOpStage : public nsAHtml5TreeOpSink {
|
||||||
* Flush the operations from the tree operations from the argument
|
* Flush the operations from the tree operations from the argument
|
||||||
* queue unconditionally.
|
* queue unconditionally.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] virtual bool MoveOpsFrom(
|
virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the staged operations into the argument.
|
* Retrieve the staged operations into the argument.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool MoveOpsTo(nsTArray<nsHtml5TreeOperation>& aOpQueue);
|
void MoveOpsTo(nsTArray<nsHtml5TreeOperation>& aOpQueue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the staged operations and speculative loads into the arguments.
|
* Retrieve the staged operations and speculative loads into the arguments.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool MoveOpsAndSpeculativeLoadsTo(
|
void MoveOpsAndSpeculativeLoadsTo(
|
||||||
nsTArray<nsHtml5TreeOperation>& aOpQueue,
|
nsTArray<nsHtml5TreeOperation>& aOpQueue,
|
||||||
nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue);
|
nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue