Bug 515338 - Make HTML5 parser internals not hold nsIContent or regular dynamic atoms. r=bnewman.
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
|
||||
class nsHtml5TreeOpExecutor;
|
||||
|
||||
@@ -52,16 +53,45 @@ enum eHtml5TreeOperation {
|
||||
eTreeOpAppendToDocument,
|
||||
eTreeOpAddAttributes,
|
||||
eTreeOpDocumentMode,
|
||||
eTreeOpCreateElement,
|
||||
eTreeOpSetFormElement,
|
||||
eTreeOpCreateTextNode,
|
||||
eTreeOpCreateComment,
|
||||
eTreeOpCreateDoctype,
|
||||
// Gecko-specific on-pop ops
|
||||
eTreeOpRunScript,
|
||||
eTreeOpDoneAddingChildren,
|
||||
eTreeOpDoneCreatingElement,
|
||||
eTreeOpUpdateStyleSheet,
|
||||
eTreeOpProcessBase,
|
||||
eTreeOpProcessMeta,
|
||||
eTreeOpProcessOfflineManifest,
|
||||
eTreeOpMarkMalformedIfScript,
|
||||
eTreeOpStartLayout
|
||||
};
|
||||
|
||||
class nsHtml5TreeOperationStringPair {
|
||||
private:
|
||||
nsString mPublicId;
|
||||
nsString mSystemId;
|
||||
public:
|
||||
nsHtml5TreeOperationStringPair(const nsAString& aPublicId,
|
||||
const nsAString& aSystemId)
|
||||
: mPublicId(aPublicId)
|
||||
, mSystemId(aSystemId) {
|
||||
MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair);
|
||||
}
|
||||
|
||||
~nsHtml5TreeOperationStringPair() {
|
||||
MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair);
|
||||
}
|
||||
|
||||
inline void Get(nsAString& aPublicId, nsAString& aSystemId) {
|
||||
aPublicId.Assign(mPublicId);
|
||||
aSystemId.Assign(mSystemId);
|
||||
}
|
||||
};
|
||||
|
||||
class nsHtml5TreeOperation {
|
||||
|
||||
public:
|
||||
@@ -69,54 +99,113 @@ class nsHtml5TreeOperation {
|
||||
|
||||
~nsHtml5TreeOperation();
|
||||
|
||||
inline void Init(nsIContent* aNode, nsIContent* aParent) {
|
||||
mNode = aNode;
|
||||
mParent = aParent;
|
||||
inline void Init(nsIContent** aNode, nsIContent** aParent) {
|
||||
mOne.node = aNode;
|
||||
mTwo.node = aParent;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, nsIContent* aNode) {
|
||||
inline void Init(eHtml5TreeOperation aOpCode, nsIContent** aNode) {
|
||||
mOpCode = aOpCode;
|
||||
mNode = aNode;
|
||||
mOne.node = aNode;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode,
|
||||
nsIContent* aNode,
|
||||
nsIContent* aParent) {
|
||||
nsIContent** aNode,
|
||||
nsIContent** aParent) {
|
||||
mOpCode = aOpCode;
|
||||
mNode = aNode;
|
||||
mParent = aParent;
|
||||
mOne.node = aNode;
|
||||
mTwo.node = aParent;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode,
|
||||
nsIContent* aNode,
|
||||
nsIContent* aParent,
|
||||
nsIContent* aTable) {
|
||||
nsIContent** aNode,
|
||||
nsIContent** aParent,
|
||||
nsIContent** aTable) {
|
||||
mOpCode = aOpCode;
|
||||
mNode = aNode;
|
||||
mParent = aParent;
|
||||
mTable = aTable;
|
||||
mOne.node = aNode;
|
||||
mTwo.node = aParent;
|
||||
mThree.node = aTable;
|
||||
}
|
||||
|
||||
inline void Init(nsHtml5DocumentMode aMode) {
|
||||
mOpCode = eTreeOpDocumentMode;
|
||||
mMode = aMode;
|
||||
mOne.mode = aMode;
|
||||
}
|
||||
|
||||
inline void Init(PRInt32 aNamespace,
|
||||
nsIAtom* aName,
|
||||
nsHtml5HtmlAttributes* aAttributes,
|
||||
nsIContent** aTarget) {
|
||||
mOpCode = eTreeOpCreateElement;
|
||||
mInt = aNamespace;
|
||||
mOne.node = aTarget;
|
||||
mTwo.atom = aName;
|
||||
if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
|
||||
mThree.attributes = nsnull;
|
||||
} else {
|
||||
mThree.attributes = aAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
inline void DoTraverse(nsCycleCollectionTraversalCallback &cb) {
|
||||
nsHtml5TreeOperation* tmp = this;
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNode);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTable);
|
||||
inline void Init(eHtml5TreeOperation aOpCode,
|
||||
PRUnichar* aBuffer,
|
||||
PRInt32 aLength,
|
||||
nsIContent** aTarget) {
|
||||
mOpCode = aOpCode;
|
||||
mOne.node = aTarget;
|
||||
mTwo.unicharPtr = aBuffer;
|
||||
mInt = aLength;
|
||||
}
|
||||
|
||||
inline void Init(nsIContent** aElement,
|
||||
nsHtml5HtmlAttributes* aAttributes) {
|
||||
mOpCode = eTreeOpAddAttributes;
|
||||
mOne.node = aElement;
|
||||
mTwo.attributes = aAttributes;
|
||||
}
|
||||
|
||||
inline void Init(nsIAtom* aName,
|
||||
const nsAString& aPublicId,
|
||||
const nsAString& aSystemId, nsIContent** aTarget) {
|
||||
mOpCode = eTreeOpCreateDoctype;
|
||||
mOne.atom = aName;
|
||||
mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
|
||||
mThree.node = aTarget;
|
||||
}
|
||||
|
||||
inline PRBool IsRunScript() {
|
||||
return mOpCode == eTreeOpRunScript;
|
||||
}
|
||||
|
||||
nsresult Perform(nsHtml5TreeOpExecutor* aBuilder);
|
||||
|
||||
inline already_AddRefed<nsIAtom> Reget(nsIAtom* aAtom) {
|
||||
if (!aAtom || aAtom->IsStaticAtom()) {
|
||||
return aAtom;
|
||||
}
|
||||
nsAutoString str;
|
||||
aAtom->ToString(str);
|
||||
return do_GetAtom(str);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// possible optimization:
|
||||
// Make the queue take items the size of pointer and make the op code
|
||||
// decide how many operands it dequeues after it.
|
||||
eHtml5TreeOperation mOpCode;
|
||||
nsCOMPtr<nsIContent> mNode;
|
||||
nsCOMPtr<nsIContent> mParent;
|
||||
nsCOMPtr<nsIContent> mTable;
|
||||
nsHtml5DocumentMode mMode; // space-wasting temporary solution
|
||||
union {
|
||||
nsIContent** node;
|
||||
nsIAtom* atom;
|
||||
nsHtml5HtmlAttributes* attributes;
|
||||
nsHtml5DocumentMode mode;
|
||||
PRUnichar* unicharPtr;
|
||||
nsHtml5TreeOperationStringPair* stringPair;
|
||||
} mOne, mTwo, mThree;
|
||||
PRInt32 mInt; // optimize this away later by using an end
|
||||
// pointer instead of string length and distinct
|
||||
// element creation opcodes for HTML, MathML and
|
||||
// SVG.
|
||||
};
|
||||
|
||||
#endif // nsHtml5TreeOperation_h__
|
||||
|
||||
Reference in New Issue
Block a user