mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Back out changeset fc4ddddf142d and changeset d1766aec3d7e due to jsreftest orange.
This commit is contained in:
parent
1c978c415e
commit
df4d9f2647
@ -77,13 +77,6 @@ nsHtml5OwningUTF16Buffer::FalliblyCreate(PRInt32 aLength)
|
||||
return newObj.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5OwningUTF16Buffer::Swap(nsHtml5OwningUTF16Buffer* aOther)
|
||||
{
|
||||
nsHtml5UTF16Buffer::Swap(aOther);
|
||||
}
|
||||
|
||||
|
||||
// Not using macros for AddRef and Release in order to be able to refcount on
|
||||
// and create on different threads.
|
||||
|
||||
|
@ -75,11 +75,6 @@ class nsHtml5OwningUTF16Buffer : public nsHtml5UTF16Buffer
|
||||
static already_AddRefed<nsHtml5OwningUTF16Buffer>
|
||||
FalliblyCreate(PRInt32 aLength);
|
||||
|
||||
/**
|
||||
* Swap start, end and buffer fields with another object.
|
||||
*/
|
||||
void Swap(nsHtml5OwningUTF16Buffer* aOther);
|
||||
|
||||
nsrefcnt AddRef();
|
||||
nsrefcnt Release();
|
||||
private:
|
||||
|
@ -287,103 +287,25 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
||||
NS_ASSERTION(!mStreamParser,
|
||||
"Had stream parser but got document.close().");
|
||||
mDocumentClosed = true;
|
||||
if (!mBlocked && !mInDocumentWrite) {
|
||||
if (!mBlocked) {
|
||||
ParseUntilBlocked();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we got this far, we are dealing with a document.write or
|
||||
// document.writeln call--not document.close().
|
||||
|
||||
NS_ASSERTION(IsInsertionPointDefined(),
|
||||
"Doc.write reached parser with undefined insertion point.");
|
||||
|
||||
NS_ASSERTION(!(mStreamParser && !aKey),
|
||||
"Got a null key in a non-script-created parser");
|
||||
|
||||
// XXX is this optimization bogus?
|
||||
if (aSourceBuffer.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This guard is here to prevent document.close from tokenizing synchronously
|
||||
// while a document.write (that wrote the script that called document.close!)
|
||||
// is still on the call stack.
|
||||
mozilla::AutoRestore<bool> guard(mInDocumentWrite);
|
||||
mInDocumentWrite = true;
|
||||
|
||||
// The script is identified by aKey. If there's nothing in the buffer
|
||||
// chain for that key, we'll insert at the head of the queue.
|
||||
// When the script leaves something in the queue, a zero-length
|
||||
// key-holder "buffer" is inserted in the queue. If the same script
|
||||
// leaves something in the chain again, it will be inserted immediately
|
||||
// before the old key holder belonging to the same script.
|
||||
//
|
||||
// We don't do the actual data insertion yet in the hope that the data gets
|
||||
// tokenized and there no data or less data to copy to the heap after
|
||||
// tokenization. Also, this way, we avoid inserting one empty data buffer
|
||||
// per document.write, which matters for performance when the parser isn't
|
||||
// blocked and a badly-authored script calls document.write() once per
|
||||
// input character. (As seen in a benchmark!)
|
||||
//
|
||||
// The insertion into the input stream happens conceptually before anything
|
||||
// gets tokenized. To make sure multi-level document.write works right,
|
||||
// it's necessary to establish the location of our parser key up front
|
||||
// in case this is the first write with this key.
|
||||
//
|
||||
// In a document.open() case, the first write level has a null key, so that
|
||||
// case is handled separately, because normal buffers containing data
|
||||
// have null keys.
|
||||
|
||||
nsHtml5OwningUTF16Buffer* prevSearchBuf = nsnull;
|
||||
nsHtml5OwningUTF16Buffer* firstLevelMarker = nsnull;
|
||||
|
||||
if (aKey) {
|
||||
if (mFirstBuffer == mLastBuffer) {
|
||||
nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey);
|
||||
keyHolder->next = mLastBuffer;
|
||||
mFirstBuffer = keyHolder;
|
||||
} else {
|
||||
prevSearchBuf = mFirstBuffer;
|
||||
for (;;) {
|
||||
if (prevSearchBuf->next == mLastBuffer) {
|
||||
// key was not found
|
||||
nsHtml5OwningUTF16Buffer* keyHolder =
|
||||
new nsHtml5OwningUTF16Buffer(aKey);
|
||||
keyHolder->next = mFirstBuffer;
|
||||
mFirstBuffer = keyHolder;
|
||||
prevSearchBuf = nsnull;
|
||||
break;
|
||||
}
|
||||
if (prevSearchBuf->next->key == aKey) {
|
||||
// found a key holder
|
||||
break;
|
||||
}
|
||||
prevSearchBuf = prevSearchBuf->next;
|
||||
}
|
||||
}
|
||||
// prevSearchBuf is the previous buffer before the keyholder or null if
|
||||
// there isn't one.
|
||||
} else {
|
||||
// We have a first-level write in the document.open() case. We insert
|
||||
// before mLastBuffer. We need to put a marker there, because otherwise
|
||||
// additional document.writes from nested event loops would insert in the
|
||||
// wrong place. Sigh.
|
||||
firstLevelMarker = new nsHtml5OwningUTF16Buffer((void*)nsnull);
|
||||
if (mFirstBuffer == mLastBuffer) {
|
||||
firstLevelMarker->next = mLastBuffer;
|
||||
mFirstBuffer = firstLevelMarker;
|
||||
} else {
|
||||
prevSearchBuf = mFirstBuffer;
|
||||
while (prevSearchBuf->next != mLastBuffer) {
|
||||
prevSearchBuf = prevSearchBuf->next;
|
||||
}
|
||||
firstLevelMarker->next = mLastBuffer;
|
||||
prevSearchBuf->next = firstLevelMarker;
|
||||
}
|
||||
}
|
||||
|
||||
nsHtml5DependentUTF16Buffer stackBuffer(aSourceBuffer);
|
||||
|
||||
while (!mBlocked && stackBuffer.hasMore()) {
|
||||
@ -433,35 +355,60 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
if (heapBuffer) {
|
||||
// We have something to insert before the keyholder holding in the non-null
|
||||
// aKey case and we have something to swap into firstLevelMarker in the
|
||||
// null aKey case.
|
||||
// The buffer is inserted to the stream here in case it won't be parsed
|
||||
// to completion.
|
||||
// The script is identified by aKey. If there's nothing in the buffer
|
||||
// chain for that key, we'll insert at the head of the queue.
|
||||
// When the script leaves something in the queue, a zero-length
|
||||
// key-holder "buffer" is inserted in the queue. If the same script
|
||||
// leaves something in the chain again, it will be inserted immediately
|
||||
// before the old key holder belonging to the same script.
|
||||
nsHtml5OwningUTF16Buffer* prevSearchBuf = nsnull;
|
||||
nsHtml5OwningUTF16Buffer* searchBuf = mFirstBuffer;
|
||||
|
||||
// after document.open, the first level of document.write has null key
|
||||
if (aKey) {
|
||||
NS_ASSERTION(mFirstBuffer != mLastBuffer,
|
||||
"Where's the keyholder?");
|
||||
// the key holder is still somewhere further down the list from
|
||||
// prevSearchBuf (which may be null)
|
||||
if (mFirstBuffer->key == aKey) {
|
||||
NS_ASSERTION(!prevSearchBuf,
|
||||
"Non-null prevSearchBuf when mFirstBuffer is the key holder?");
|
||||
heapBuffer->next = mFirstBuffer;
|
||||
while (searchBuf != mLastBuffer) {
|
||||
if (searchBuf->key == aKey) {
|
||||
// found a key holder
|
||||
// now insert the new buffer between the previous buffer
|
||||
// and the key holder if we have a buffer left.
|
||||
if (heapBuffer) {
|
||||
heapBuffer->next = searchBuf;
|
||||
if (prevSearchBuf) {
|
||||
prevSearchBuf->next = heapBuffer;
|
||||
} else {
|
||||
mFirstBuffer = heapBuffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
prevSearchBuf = searchBuf;
|
||||
searchBuf = searchBuf->next;
|
||||
}
|
||||
if (searchBuf == mLastBuffer) {
|
||||
// key was not found
|
||||
nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey);
|
||||
keyHolder->next = mFirstBuffer;
|
||||
if (heapBuffer) {
|
||||
heapBuffer->next = keyHolder;
|
||||
mFirstBuffer = heapBuffer;
|
||||
} else {
|
||||
if (!prevSearchBuf) {
|
||||
prevSearchBuf = mFirstBuffer;
|
||||
mFirstBuffer = keyHolder;
|
||||
}
|
||||
// We created a key holder earlier, so we will find it without walking
|
||||
// past the end of the list.
|
||||
while (prevSearchBuf->next->key != aKey) {
|
||||
prevSearchBuf = prevSearchBuf->next;
|
||||
}
|
||||
heapBuffer->next = prevSearchBuf->next;
|
||||
} else if (heapBuffer) {
|
||||
// we have a first level document.write after document.open()
|
||||
// insert immediately before mLastBuffer
|
||||
while (searchBuf != mLastBuffer) {
|
||||
prevSearchBuf = searchBuf;
|
||||
searchBuf = searchBuf->next;
|
||||
}
|
||||
heapBuffer->next = mLastBuffer;
|
||||
if (prevSearchBuf) {
|
||||
prevSearchBuf->next = heapBuffer;
|
||||
}
|
||||
} else {
|
||||
NS_ASSERTION(firstLevelMarker, "How come we don't have a marker.");
|
||||
firstLevelMarker->Swap(heapBuffer);
|
||||
mFirstBuffer = heapBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -710,12 +657,14 @@ nsHtml5Parser::ParseUntilBlocked()
|
||||
NS_PRECONDITION(!mExecutor->IsFragmentMode(),
|
||||
"ParseUntilBlocked called in fragment mode.");
|
||||
|
||||
if (mBlocked || mExecutor->IsComplete() || mExecutor->IsBroken()) {
|
||||
if (mBlocked ||
|
||||
mExecutor->IsComplete() ||
|
||||
mExecutor->IsBroken() ||
|
||||
mInDocumentWrite) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle.");
|
||||
NS_ASSERTION(!mInDocumentWrite,
|
||||
"ParseUntilBlocked entered while in doc.write!");
|
||||
|
||||
mDocWriteSpeculatorActive = false;
|
||||
|
||||
|
@ -53,17 +53,3 @@ nsHtml5UTF16Buffer::DeleteBuffer()
|
||||
{
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5UTF16Buffer::Swap(nsHtml5UTF16Buffer* aOther)
|
||||
{
|
||||
PRUnichar* tempBuffer = buffer;
|
||||
PRInt32 tempStart = start;
|
||||
PRInt32 tempEnd = end;
|
||||
buffer = aOther->buffer;
|
||||
start = aOther->start;
|
||||
end = aOther->end;
|
||||
aOther->buffer = tempBuffer;
|
||||
aOther->start = tempStart;
|
||||
aOther->end = tempEnd;
|
||||
}
|
||||
|
@ -43,8 +43,3 @@ protected:
|
||||
* For working around the privacy of |buffer| in the generated code.
|
||||
*/
|
||||
void DeleteBuffer();
|
||||
|
||||
/**
|
||||
* For working around the privacy of |buffer| in the generated code.
|
||||
*/
|
||||
void Swap(nsHtml5UTF16Buffer* aOther);
|
||||
|
@ -1 +0,0 @@
|
||||
<!DOCTYPE html>CcBbAa
|
@ -1,2 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<body><script>document.write("\u003cscript>document.write(\"\\u003cscript src='bug696651-external.js'>\\u003c/script>B\"); document.write(\"b\");\u003c/script>A"); document.write("a");</script>
|
@ -1,2 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<body><script>document.write("\u003cscript>document.write(\"\\u003cscript src='data:text/javascript,document.write(%27C%27);%20document.write(%27c%27);'>\\u003c/script>B\"); document.write(\"b\");\u003c/script>A"); document.write("a");</script>
|
@ -1 +0,0 @@
|
||||
<!DOCTYPE html><iframe src="data:text/html,<!DOCTYPE html>CcBbAa"></iframe>
|
@ -1,6 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
<script>
|
||||
var doc = document.getElementsByTagName("iframe")[0].contentDocument;
|
||||
doc.open(); doc.write("\u003cscript>document.write(\"\\u003cscript src='bug696651-external.js'>\\u003c/script>B\"); document.write(\"b\");\u003c/script>A"); doc.write("a"); doc.close();</script>
|
@ -1,6 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
<script>
|
||||
var doc = document.getElementsByTagName("iframe")[0].contentDocument;
|
||||
doc.open(); doc.write("\u003cscript>document.write(\"\\u003cscript src='data:text/javascript,document.write(%27C%27);%20document.write(%27c%27);'>\\u003c/script>B\"); document.write(\"b\");\u003c/script>A"); doc.write("a"); doc.close();</script>
|
@ -1 +0,0 @@
|
||||
document.write("C"); document.write("c");
|
@ -5,5 +5,3 @@
|
||||
== bug592656-1.html bug592656-1-ref.html
|
||||
== bug608373-1.html bug608373-1-ref.html
|
||||
== view-source:bug673094-1.html view-source:bug673094-1-ref.html
|
||||
== bug696651-1.html bug696651-1-ref.html
|
||||
== bug696651-2.html bug696651-2-ref.html
|
||||
|
Loading…
Reference in New Issue
Block a user