Bug 503190 - Include assertions in the C++ translator output. r=smaug.
authorHenri Sivonen <hsivonen@iki.fi>
Mon, 01 Oct 2012 11:52:32 +0300
changeset 108847 1caa3c482541911876778e6f1c26e95975a5419c
parent 108846 b7cc4a94a64942e79f5ef90478f7ab191bdfb9a6
child 108848 6362581f442e31019d0c147edb958a9fbe47d298
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewerssmaug
bugs503190
milestone18.0a1
Bug 503190 - Include assertions in the C++ translator output. r=smaug.
parser/html/javasrc/ElementName.java
parser/html/javasrc/HtmlAttributes.java
parser/html/javasrc/Tokenizer.java
parser/html/javasrc/TreeBuilder.java
parser/html/nsHtml5ElementName.cpp
parser/html/nsHtml5ElementName.h
parser/html/nsHtml5HtmlAttributes.cpp
parser/html/nsHtml5StackNode.cpp
parser/html/nsHtml5Tokenizer.cpp
parser/html/nsHtml5TreeBuilder.cpp
parser/html/nsHtml5TreeBuilder.h
--- a/parser/html/javasrc/ElementName.java
+++ b/parser/html/javasrc/ElementName.java
@@ -98,23 +98,19 @@ public final class ElementName
     @Inline public int getFlags() {
         return flags;
     }
     
     public int getGroup() {
         return flags & GROUP_MASK;
     }
     
-    // [NOCPP[
-    
     public boolean isCustom() {
         return (flags & CUSTOM) != 0;
     }
-    
-    // ]NOCPP]
 
     static ElementName elementNameByBuffer(@NoLength char[] buf, int offset, int length, Interner interner) {
         int hash = ElementName.bufToHash(buf, length);
         int index = Arrays.binarySearch(ElementName.ELEMENT_HASHES, hash);
         if (index < 0) {
             return new ElementName(Portability.newLocalNameFromBuffer(buf, offset, length, interner));
         } else {
             ElementName elementName = ElementName.ELEMENT_NAMES[index];
--- a/parser/html/javasrc/HtmlAttributes.java
+++ b/parser/html/javasrc/HtmlAttributes.java
@@ -500,35 +500,42 @@ public final class HtmlAttributes implem
     public void adjustForMath() {
         mode = AttributeName.MATHML;
     }
 
     public void adjustForSvg() {
         mode = AttributeName.SVG;
     }
 
-    public HtmlAttributes cloneAttributes(Interner interner) throws SAXException {
-        assert (length == 0 && xmlnsLength == 0) || mode == 0 || mode == 3;
+    public HtmlAttributes cloneAttributes(Interner interner)
+            throws SAXException {
+        assert (length == 0
+                // [NOCPP[
+                && xmlnsLength == 0
+                // ]NOCPP]
+                )
+                || mode == 0 || mode == 3;
         HtmlAttributes clone = new HtmlAttributes(0);
         for (int i = 0; i < length; i++) {
-            clone.addAttribute(names[i].cloneAttributeName(interner), Portability.newStringFromString(values[i])
-            // [NOCPP[
-                   , XmlViolationPolicy.ALLOW
-            // ]NOCPP]
+            clone.addAttribute(names[i].cloneAttributeName(interner),
+                    Portability.newStringFromString(values[i])
+                    // [NOCPP[
+                    , XmlViolationPolicy.ALLOW
+                    // ]NOCPP]
             );
         }
         // [NOCPP[
         for (int i = 0; i < xmlnsLength; i++) {
-            clone.addAttribute(xmlnsNames[i],
-                    xmlnsValues[i], XmlViolationPolicy.ALLOW);
+            clone.addAttribute(xmlnsNames[i], xmlnsValues[i],
+                    XmlViolationPolicy.ALLOW);
         }
         // ]NOCPP]
         return clone; // XXX!!!
     }
-    
+
     public boolean equalsAnother(HtmlAttributes other) {
         assert mode == 0 || mode == 3 : "Trying to compare attributes in foreign content.";
         int otherLength = other.getLength();
         if (length != otherLength) {
             return false;
         }
         for (int i = 0; i < length; i++) {
             // Work around the limitations of C++
--- a/parser/html/javasrc/Tokenizer.java
+++ b/parser/html/javasrc/Tokenizer.java
@@ -4238,17 +4238,17 @@ public class Tokenizer implements Locato
                     }
                     // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
                 case SCRIPT_DATA_DOUBLE_ESCAPE_START:
                     scriptdatadoubleescapestartloop: for (;;) {
                         if (++pos == endPos) {
                             break stateloop;
                         }
                         c = checkChar(buf, pos);
-                        assert (index > 0);
+                        assert index > 0;
                         if (index < 6) { // SCRIPT_ARR.length
                             char folded = c;
                             if (c >= 'A' && c <= 'Z') {
                                 folded += 0x20;
                             }
                             if (folded != Tokenizer.SCRIPT_ARR[index]) {
                                 reconsume = true;
                                 state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -793,20 +793,19 @@ public abstract class TreeBuilder<T> imp
                             } else {
                                 if (firstCommentLocation != null) {
                                     warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation);
                                 }
                                 if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) {
                                     if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) {
                                         warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
                                     }
-                                } else {
-                                    if (!(publicIdentifier == null && systemIdentifier == null)) {
-                                        err("Legacy doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                                    }
+                                } else if (!((systemIdentifier == null || Portability.literalEqualsString(
+                                        "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) {
+                                    err("Legacy doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
                                 }
                                 documentModeInternal(
                                         DocumentMode.STANDARDS_MODE,
                                         publicIdentifier, systemIdentifier,
                                         html4);
                             }
                             break;
                         case NO_DOCTYPE_ERRORS:
@@ -4177,22 +4176,22 @@ public abstract class TreeBuilder<T> imp
         if (errorHandler != null && eltPos != currentPtr) {
             errUnclosedElementsImplied(eltPos, "p");
         }
         while (currentPtr >= eltPos) {
             pop();
         }
     }
 
-    private boolean clearLastStackSlot() {
+    private boolean debugOnlyClearLastStackSlot() {
         stack[currentPtr] = null;
         return true;
     }
 
-    private boolean clearLastListSlot() {
+    private boolean debugOnlyClearLastListSlot() {
         listOfActiveFormattingElements[listPtr] = null;
         return true;
     }
 
     @SuppressWarnings("unchecked") private void push(StackNode<T> node) throws SAXException {
         currentPtr++;
         if (currentPtr == stack.length) {
             StackNode<T>[] newStack = new StackNode[stack.length + 64];
@@ -4245,17 +4244,17 @@ public abstract class TreeBuilder<T> imp
 
     private void removeFromStack(int pos) throws SAXException {
         if (currentPtr == pos) {
             pop();
         } else {
             fatal();
             stack[pos].release();
             System.arraycopy(stack, pos + 1, stack, pos, currentPtr - pos);
-            assert clearLastStackSlot();
+            assert debugOnlyClearLastStackSlot();
             currentPtr--;
         }
     }
 
     private void removeFromStack(StackNode<T> node) throws SAXException {
         if (stack[currentPtr] == node) {
             pop();
         } else {
@@ -4273,24 +4272,24 @@ public abstract class TreeBuilder<T> imp
             currentPtr--;
         }
     }
 
     private void removeFromListOfActiveFormattingElements(int pos) {
         assert listOfActiveFormattingElements[pos] != null;
         listOfActiveFormattingElements[pos].release();
         if (pos == listPtr) {
-            assert clearLastListSlot();
+            assert debugOnlyClearLastListSlot();
             listPtr--;
             return;
         }
         assert pos < listPtr;
         System.arraycopy(listOfActiveFormattingElements, pos + 1,
                 listOfActiveFormattingElements, pos, listPtr - pos);
-        assert clearLastListSlot();
+        assert debugOnlyClearLastListSlot();
         listPtr--;
     }
 
     private boolean adoptionAgencyEndTag(@Local String name) throws SAXException {
         // If you crash around here, perhaps some stack node variable claimed to
         // be a weak ref isn't.
         for (int i = 0; i < 8; ++i) {
             int formattingEltListPos = listPtr;
@@ -4650,32 +4649,32 @@ public abstract class TreeBuilder<T> imp
                 return true;
             }
         }
         return false;
     }
 
     private void pop() throws SAXException {
         StackNode<T> node = stack[currentPtr];
-        assert clearLastStackSlot();
+        assert debugOnlyClearLastStackSlot();
         currentPtr--;
         elementPopped(node.ns, node.popName, node.node);
         node.release();
     }
 
     private void silentPop() throws SAXException {
         StackNode<T> node = stack[currentPtr];
-        assert clearLastStackSlot();
+        assert debugOnlyClearLastStackSlot();
         currentPtr--;
         node.release();
     }
 
     private void popOnEof() throws SAXException {
         StackNode<T> node = stack[currentPtr];
-        assert clearLastStackSlot();
+        assert debugOnlyClearLastStackSlot();
         currentPtr--;
         markMalformedIfScript(node.node);
         elementPopped(node.ns, node.popName, node.node);
         node.release();
     }
 
     // [NOCPP[
     private void checkAttributes(HtmlAttributes attributes, @NsUri String ns)
--- a/parser/html/nsHtml5ElementName.cpp
+++ b/parser/html/nsHtml5ElementName.cpp
@@ -57,16 +57,22 @@
 
 nsHtml5ElementName* nsHtml5ElementName::ELT_NULL_ELEMENT_NAME = nullptr;
 int32_t 
 nsHtml5ElementName::getGroup()
 {
   return flags & NS_HTML5ELEMENT_NAME_GROUP_MASK;
 }
 
+bool 
+nsHtml5ElementName::isCustom()
+{
+  return (flags & NS_HTML5ELEMENT_NAME_CUSTOM);
+}
+
 nsHtml5ElementName* 
 nsHtml5ElementName::elementNameByBuffer(PRUnichar* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner)
 {
   int32_t hash = nsHtml5ElementName::bufToHash(buf, length);
   int32_t index = nsHtml5ElementName::ELEMENT_HASHES.binarySearch(hash);
   if (index < 0) {
     return new nsHtml5ReleasableElementName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
   } else {
--- a/parser/html/nsHtml5ElementName.h
+++ b/parser/html/nsHtml5ElementName.h
@@ -63,16 +63,17 @@ class nsHtml5ElementName
     nsIAtom* camelCaseName;
     int32_t flags;
     inline int32_t getFlags()
     {
       return flags;
     }
 
     int32_t getGroup();
+    bool isCustom();
     static nsHtml5ElementName* elementNameByBuffer(PRUnichar* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner);
   private:
     static int32_t bufToHash(PRUnichar* buf, int32_t len);
     nsHtml5ElementName(nsIAtom* name, nsIAtom* camelCaseName, int32_t flags);
   protected:
     nsHtml5ElementName(nsIAtom* name);
   public:
     virtual void release();
--- a/parser/html/nsHtml5HtmlAttributes.cpp
+++ b/parser/html/nsHtml5HtmlAttributes.cpp
@@ -99,45 +99,45 @@ int32_t
 nsHtml5HtmlAttributes::getLength()
 {
   return length;
 }
 
 nsIAtom* 
 nsHtml5HtmlAttributes::getLocalNameNoBoundsCheck(int32_t index)
 {
-
+  MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
   return names[index]->getLocal(mode);
 }
 
 int32_t 
 nsHtml5HtmlAttributes::getURINoBoundsCheck(int32_t index)
 {
-
+  MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
   return names[index]->getUri(mode);
 }
 
 nsIAtom* 
 nsHtml5HtmlAttributes::getPrefixNoBoundsCheck(int32_t index)
 {
-
+  MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
   return names[index]->getPrefix(mode);
 }
 
 nsString* 
 nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t index)
 {
-
+  MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
   return values[index];
 }
 
 nsHtml5AttributeName* 
 nsHtml5HtmlAttributes::getAttributeNameNoBoundsCheck(int32_t index)
 {
-
+  MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
   return names[index];
 }
 
 void 
 nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name, nsString* value)
 {
   if (names.length == length) {
     int32_t newLen = length << 1;
@@ -203,28 +203,28 @@ void
 nsHtml5HtmlAttributes::adjustForSvg()
 {
   mode = NS_HTML5ATTRIBUTE_NAME_SVG;
 }
 
 nsHtml5HtmlAttributes* 
 nsHtml5HtmlAttributes::cloneAttributes(nsHtml5AtomTable* interner)
 {
-
+  MOZ_ASSERT((!length) || !mode || mode == 3);
   nsHtml5HtmlAttributes* clone = new nsHtml5HtmlAttributes(0);
   for (int32_t i = 0; i < length; i++) {
     clone->addAttribute(names[i]->cloneAttributeName(interner), nsHtml5Portability::newStringFromString(values[i]));
   }
   return clone;
 }
 
 bool 
 nsHtml5HtmlAttributes::equalsAnother(nsHtml5HtmlAttributes* other)
 {
-
+  MOZ_ASSERT(!mode || mode == 3, "Trying to compare attributes in foreign content.");
   int32_t otherLength = other->getLength();
   if (length != otherLength) {
     return false;
   }
   for (int32_t i = 0; i < length; i++) {
     bool found = false;
     nsIAtom* ownLocal = names[i]->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML);
     for (int32_t j = 0; j < otherLength; j++) {
--- a/parser/html/nsHtml5StackNode.cpp
+++ b/parser/html/nsHtml5StackNode.cpp
@@ -104,31 +104,31 @@ nsHtml5StackNode::nsHtml5StackNode(nsHtm
     name(elementName->name),
     popName(elementName->name),
     ns(kNameSpaceID_XHTML),
     node(node),
     attributes(nullptr),
     refcount(1)
 {
   MOZ_COUNT_CTOR(nsHtml5StackNode);
-
+  MOZ_ASSERT(!elementName->isCustom(), "Don't use this constructor for custom elements.");
 }
 
 
 nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node, nsHtml5HtmlAttributes* attributes)
   : flags(elementName->getFlags()),
     name(elementName->name),
     popName(elementName->name),
     ns(kNameSpaceID_XHTML),
     node(node),
     attributes(attributes),
     refcount(1)
 {
   MOZ_COUNT_CTOR(nsHtml5StackNode);
-
+  MOZ_ASSERT(!elementName->isCustom(), "Don't use this constructor for custom elements.");
 }
 
 
 nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node, nsIAtom* popName)
   : flags(elementName->getFlags()),
     name(elementName->name),
     popName(popName),
     ns(kNameSpaceID_XHTML),
--- a/parser/html/nsHtml5Tokenizer.cpp
+++ b/parser/html/nsHtml5Tokenizer.cpp
@@ -184,17 +184,17 @@ nsHtml5Tokenizer::endTagExpectationToArr
       endTagExpectationAsArray = NOSCRIPT_ARR;
       return;
     }
     case NS_HTML5TREE_BUILDER_NOFRAMES: {
       endTagExpectationAsArray = NOFRAMES_ARR;
       return;
     }
     default: {
-
+      MOZ_ASSERT(false, "Bad end tag expectation.");
       return;
     }
   }
 }
 
 void 
 nsHtml5Tokenizer::setLineNumber(int32_t line)
 {
@@ -2396,17 +2396,17 @@ nsHtml5Tokenizer::stateLoop(int32_t stat
         scriptdataescapedlessthanloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START: {
         for (; ; ) {
           if (++pos == endPos) {
             NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
-
+          MOZ_ASSERT(index > 0);
           if (index < 6) {
             PRUnichar folded = c;
             if (c >= 'A' && c <= 'Z') {
               folded += 0x20;
             }
             if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
               reconsume = true;
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -484,17 +484,17 @@ nsHtml5TreeBuilder::eof()
       }
       case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
         appendToCurrentNodeAndPushBodyElement();
         mode = NS_HTML5TREE_BUILDER_IN_BODY;
         continue;
       }
       case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
         if (!currentPtr) {
-
+          MOZ_ASSERT(fragment);
           NS_HTML5_BREAK(eofloop);
         } else {
           popOnEof();
           mode = NS_HTML5TREE_BUILDER_IN_TABLE;
           continue;
         }
       }
       case NS_HTML5TREE_BUILDER_FRAMESET_OK:
@@ -683,17 +683,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
           }
           case NS_HTML5TREE_BUILDER_CAPTION:
           case NS_HTML5TREE_BUILDER_COL:
           case NS_HTML5TREE_BUILDER_COLGROUP:
           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
           case NS_HTML5TREE_BUILDER_TR: {
             eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
             if (!eltPos) {
-
+              MOZ_ASSERT(fragment);
               errNoTableRowToClose();
               NS_HTML5_BREAK(starttagloop);
             }
             clearStackBackTo(eltPos);
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
             continue;
           }
@@ -738,17 +738,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
               appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_TBODY, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
               mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
               NS_HTML5_CONTINUE(starttagloop);
             }
             case NS_HTML5TREE_BUILDER_TABLE: {
               errTableSeenWhileTableOpen();
               eltPos = findLastInTableScope(name);
               if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
+                MOZ_ASSERT(fragment);
                 NS_HTML5_BREAK(starttagloop);
               }
               generateImpliedEndTags();
               if (!!NS_UNLIKELY(mViewSource) && !isCurrent(nsHtml5Atoms::table)) {
                 errNoCheckUnclosedElementsOnStack();
               }
               while (currentPtr >= eltPos) {
                 pop();
@@ -849,17 +849,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
             ; // fall through
         }
       }
       case NS_HTML5TREE_BUILDER_FRAMESET_OK: {
         switch(group) {
           case NS_HTML5TREE_BUILDER_FRAMESET: {
             if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK) {
               if (!currentPtr || stack[1]->getGroup() != NS_HTML5TREE_BUILDER_BODY) {
-
+                MOZ_ASSERT(fragment);
                 errStrayStartTag(name);
                 NS_HTML5_BREAK(starttagloop);
               } else {
                 errFramesetStart();
                 detachFromParent(stack[1]->node);
                 while (currentPtr > 0) {
                   pop();
                 }
@@ -916,17 +916,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
             case NS_HTML5TREE_BUILDER_STYLE:
             case NS_HTML5TREE_BUILDER_SCRIPT:
             case NS_HTML5TREE_BUILDER_TITLE:
             case NS_HTML5TREE_BUILDER_COMMAND: {
               NS_HTML5_BREAK(inbodyloop);
             }
             case NS_HTML5TREE_BUILDER_BODY: {
               if (!currentPtr || stack[1]->getGroup() != NS_HTML5TREE_BUILDER_BODY) {
-
+                MOZ_ASSERT(fragment);
                 errStrayStartTag(name);
                 NS_HTML5_BREAK(starttagloop);
               }
               errFooSeenWhenFooOpen(name);
               framesetOk = false;
               if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK) {
                 mode = NS_HTML5TREE_BUILDER_IN_BODY;
               }
@@ -1433,17 +1433,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
           case NS_HTML5TREE_BUILDER_COL: {
             appendVoidElementToCurrentMayFoster(elementName, attributes);
             selfClosing = false;
             attributes = nullptr;
             NS_HTML5_BREAK(starttagloop);
           }
           default: {
             if (!currentPtr) {
-
+              MOZ_ASSERT(fragment);
               errGarbageInColgroup();
               NS_HTML5_BREAK(starttagloop);
             }
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
             continue;
           }
         }
@@ -1453,17 +1453,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
           case NS_HTML5TREE_BUILDER_CAPTION:
           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
           case NS_HTML5TREE_BUILDER_TR:
           case NS_HTML5TREE_BUILDER_TD_OR_TH:
           case NS_HTML5TREE_BUILDER_TABLE: {
             errStartTagWithSelectOpen(name);
             eltPos = findLastInTableScope(nsHtml5Atoms::select);
             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
+              MOZ_ASSERT(fragment);
               NS_HTML5_BREAK(starttagloop);
             }
             while (currentPtr >= eltPos) {
               pop();
             }
             resetTheInsertionMode();
             continue;
           }
@@ -1499,34 +1499,34 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
             appendToCurrentNodeAndPushElement(elementName, attributes);
             attributes = nullptr;
             NS_HTML5_BREAK(starttagloop);
           }
           case NS_HTML5TREE_BUILDER_SELECT: {
             errStartSelectWhereEndSelectExpected();
             eltPos = findLastInTableScope(name);
             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
+              MOZ_ASSERT(fragment);
               errNoSelectInTableScope();
               NS_HTML5_BREAK(starttagloop);
             } else {
               while (currentPtr >= eltPos) {
                 pop();
               }
               resetTheInsertionMode();
               NS_HTML5_BREAK(starttagloop);
             }
           }
           case NS_HTML5TREE_BUILDER_INPUT:
           case NS_HTML5TREE_BUILDER_TEXTAREA:
           case NS_HTML5TREE_BUILDER_KEYGEN: {
             errStartTagWithSelectOpen(name);
             eltPos = findLastInTableScope(nsHtml5Atoms::select);
             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
+              MOZ_ASSERT(fragment);
               NS_HTML5_BREAK(starttagloop);
             }
             while (currentPtr >= eltPos) {
               pop();
             }
             resetTheInsertionMode();
             continue;
           }
@@ -1785,17 +1785,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
           }
           default: {
             errStrayStartTag(name);
             NS_HTML5_BREAK(starttagloop);
           }
         }
       }
       case NS_HTML5TREE_BUILDER_TEXT: {
-
+        MOZ_ASSERT(false);
         NS_HTML5_BREAK(starttagloop);
       }
     }
   }
   starttagloop_end: ;
   if (selfClosing) {
     errSelfClosing();
   }
@@ -2059,45 +2059,45 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
       }
     }
     switch(mode) {
       case NS_HTML5TREE_BUILDER_IN_ROW: {
         switch(group) {
           case NS_HTML5TREE_BUILDER_TR: {
             eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
             if (!eltPos) {
-
+              MOZ_ASSERT(fragment);
               errNoTableRowToClose();
               NS_HTML5_BREAK(endtagloop);
             }
             clearStackBackTo(eltPos);
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
             NS_HTML5_BREAK(endtagloop);
           }
           case NS_HTML5TREE_BUILDER_TABLE: {
             eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
             if (!eltPos) {
-
+              MOZ_ASSERT(fragment);
               errNoTableRowToClose();
               NS_HTML5_BREAK(endtagloop);
             }
             clearStackBackTo(eltPos);
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
             continue;
           }
           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
             if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
               errStrayEndTag(name);
               NS_HTML5_BREAK(endtagloop);
             }
             eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
             if (!eltPos) {
-
+              MOZ_ASSERT(fragment);
               errNoTableRowToClose();
               NS_HTML5_BREAK(endtagloop);
             }
             clearStackBackTo(eltPos);
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
             continue;
           }
@@ -2125,17 +2125,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
             clearStackBackTo(eltPos);
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
             NS_HTML5_BREAK(endtagloop);
           }
           case NS_HTML5TREE_BUILDER_TABLE: {
             eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
             if (!eltPos) {
-
+              MOZ_ASSERT(fragment);
               errStrayEndTag(name);
               NS_HTML5_BREAK(endtagloop);
             }
             clearStackBackTo(eltPos);
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
             continue;
           }
@@ -2153,17 +2153,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
             ; // fall through
         }
       }
       case NS_HTML5TREE_BUILDER_IN_TABLE: {
         switch(group) {
           case NS_HTML5TREE_BUILDER_TABLE: {
             eltPos = findLast(nsHtml5Atoms::table);
             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
+              MOZ_ASSERT(fragment);
               errStrayEndTag(name);
               NS_HTML5_BREAK(endtagloop);
             }
             while (currentPtr >= eltPos) {
               pop();
             }
             resetTheInsertionMode();
             NS_HTML5_BREAK(endtagloop);
@@ -2274,21 +2274,21 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
             ; // fall through
         }
       }
       case NS_HTML5TREE_BUILDER_FRAMESET_OK:
       case NS_HTML5TREE_BUILDER_IN_BODY: {
         switch(group) {
           case NS_HTML5TREE_BUILDER_BODY: {
             if (!isSecondOnStackBody()) {
-
+              MOZ_ASSERT(fragment);
               errStrayEndTag(name);
               NS_HTML5_BREAK(endtagloop);
             }
-
+            MOZ_ASSERT(currentPtr >= 1);
             if (NS_UNLIKELY(mViewSource)) {
               for (int32_t i = 2; i <= currentPtr; i++) {
                 switch(stack[i]->getGroup()) {
                   case NS_HTML5TREE_BUILDER_DD_OR_DT:
                   case NS_HTML5TREE_BUILDER_LI:
                   case NS_HTML5TREE_BUILDER_OPTGROUP:
                   case NS_HTML5TREE_BUILDER_OPTION:
                   case NS_HTML5TREE_BUILDER_P:
@@ -2305,17 +2305,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
               }
               uncloseloop1_end: ;
             }
             mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
             NS_HTML5_BREAK(endtagloop);
           }
           case NS_HTML5TREE_BUILDER_HTML: {
             if (!isSecondOnStackBody()) {
-
+              MOZ_ASSERT(fragment);
               errStrayEndTag(name);
               NS_HTML5_BREAK(endtagloop);
             }
             if (NS_UNLIKELY(mViewSource)) {
               for (int32_t i = 0; i <= currentPtr; i++) {
                 switch(stack[i]->getGroup()) {
                   case NS_HTML5TREE_BUILDER_DD_OR_DT:
                   case NS_HTML5TREE_BUILDER_LI:
@@ -2384,17 +2384,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
                 while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
                   pop();
                 }
               }
               appendVoidElementToCurrentMayFoster(elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
               NS_HTML5_BREAK(endtagloop);
             }
             generateImpliedEndTagsExceptFor(nsHtml5Atoms::p);
-
+            MOZ_ASSERT(eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK);
             if (!!NS_UNLIKELY(mViewSource) && eltPos != currentPtr) {
               errUnclosedElements(eltPos, name);
             }
             while (currentPtr >= eltPos) {
               pop();
             }
             NS_HTML5_BREAK(endtagloop);
           }
@@ -2532,31 +2532,31 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
             }
           }
         }
       }
       case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
         switch(group) {
           case NS_HTML5TREE_BUILDER_COLGROUP: {
             if (!currentPtr) {
-
+              MOZ_ASSERT(fragment);
               errGarbageInColgroup();
               NS_HTML5_BREAK(endtagloop);
             }
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
             NS_HTML5_BREAK(endtagloop);
           }
           case NS_HTML5TREE_BUILDER_COL: {
             errStrayEndTag(name);
             NS_HTML5_BREAK(endtagloop);
           }
           default: {
             if (!currentPtr) {
-
+              MOZ_ASSERT(fragment);
               errGarbageInColgroup();
               NS_HTML5_BREAK(endtagloop);
             }
             pop();
             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
             continue;
           }
         }
@@ -2567,17 +2567,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
           case NS_HTML5TREE_BUILDER_TABLE:
           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
           case NS_HTML5TREE_BUILDER_TR:
           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
             errEndTagSeenWithSelectOpen(name);
             if (findLastInTableScope(name) != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
               eltPos = findLastInTableScope(nsHtml5Atoms::select);
               if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
+                MOZ_ASSERT(fragment);
                 NS_HTML5_BREAK(endtagloop);
               }
               while (currentPtr >= eltPos) {
                 pop();
               }
               resetTheInsertionMode();
               continue;
             } else {
@@ -2608,17 +2608,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
             } else {
               errStrayEndTag(name);
             }
             NS_HTML5_BREAK(endtagloop);
           }
           case NS_HTML5TREE_BUILDER_SELECT: {
             eltPos = findLastInTableScope(nsHtml5Atoms::select);
             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
+              MOZ_ASSERT(fragment);
               errStrayEndTag(name);
               NS_HTML5_BREAK(endtagloop);
             }
             while (currentPtr >= eltPos) {
               pop();
             }
             resetTheInsertionMode();
             NS_HTML5_BREAK(endtagloop);
@@ -2646,17 +2646,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
             continue;
           }
         }
       }
       case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
         switch(group) {
           case NS_HTML5TREE_BUILDER_FRAMESET: {
             if (!currentPtr) {
-
+              MOZ_ASSERT(fragment);
               errStrayEndTag(name);
               NS_HTML5_BREAK(endtagloop);
             }
             pop();
             if ((!fragment) && !isCurrent(nsHtml5Atoms::frameset)) {
               mode = NS_HTML5TREE_BUILDER_AFTER_FRAMESET;
             }
             NS_HTML5_BREAK(endtagloop);
@@ -3108,24 +3108,24 @@ nsHtml5TreeBuilder::implicitlyCloseP()
     errUnclosedElementsImplied(eltPos, nsHtml5Atoms::p);
   }
   while (currentPtr >= eltPos) {
     pop();
   }
 }
 
 bool 
-nsHtml5TreeBuilder::clearLastStackSlot()
+nsHtml5TreeBuilder::debugOnlyClearLastStackSlot()
 {
   stack[currentPtr] = nullptr;
   return true;
 }
 
 bool 
-nsHtml5TreeBuilder::clearLastListSlot()
+nsHtml5TreeBuilder::debugOnlyClearLastListSlot()
 {
   listOfActiveFormattingElements[listPtr] = nullptr;
   return true;
 }
 
 void 
 nsHtml5TreeBuilder::push(nsHtml5StackNode* node)
 {
@@ -3180,17 +3180,17 @@ void
 nsHtml5TreeBuilder::removeFromStack(int32_t pos)
 {
   if (currentPtr == pos) {
     pop();
   } else {
 
     stack[pos]->release();
     nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos);
-
+    MOZ_ASSERT(debugOnlyClearLastStackSlot());
     currentPtr--;
   }
 }
 
 void 
 nsHtml5TreeBuilder::removeFromStack(nsHtml5StackNode* node)
 {
   if (stack[currentPtr] == node) {
@@ -3208,26 +3208,26 @@ nsHtml5TreeBuilder::removeFromStack(nsHt
     nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos);
     currentPtr--;
   }
 }
 
 void 
 nsHtml5TreeBuilder::removeFromListOfActiveFormattingElements(int32_t pos)
 {
-
+  MOZ_ASSERT(!!listOfActiveFormattingElements[pos]);
   listOfActiveFormattingElements[pos]->release();
   if (pos == listPtr) {
-
+    MOZ_ASSERT(debugOnlyClearLastListSlot());
     listPtr--;
     return;
   }
-
+  MOZ_ASSERT(pos < listPtr);
   nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, pos + 1, pos, listPtr - pos);
-
+  MOZ_ASSERT(debugOnlyClearLastListSlot());
   listPtr--;
 }
 
 bool 
 nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
 {
   for (int32_t i = 0; i < 8; ++i) {
     int32_t formattingEltListPos = listPtr;
@@ -3288,31 +3288,31 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag
     int32_t bookmark = formattingEltListPos;
     int32_t nodePos = furthestBlockPos;
     nsHtml5StackNode* lastNode = furthestBlock;
     for (int32_t j = 0; j < 3; ++j) {
       nodePos--;
       nsHtml5StackNode* node = stack[nodePos];
       int32_t nodeListPos = findInListOfActiveFormattingElements(node);
       if (nodeListPos == -1) {
-
-
-
+        MOZ_ASSERT(formattingEltStackPos < nodePos);
+        MOZ_ASSERT(bookmark < nodePos);
+        MOZ_ASSERT(furthestBlockPos > nodePos);
         removeFromStack(nodePos);
         furthestBlockPos--;
         continue;
       }
       if (nodePos == formattingEltStackPos) {
         break;
       }
       if (nodePos == furthestBlockPos) {
         bookmark = nodeListPos + 1;
       }
-
-
+      MOZ_ASSERT(node == listOfActiveFormattingElements[nodeListPos]);
+      MOZ_ASSERT(node == stack[nodePos]);
       nsIContent** clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr));
       nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, clone, node->popName, node->attributes);
       node->dropAttributes();
       stack[nodePos] = newNode;
       newNode->retain();
       listOfActiveFormattingElements[nodeListPos] = newNode;
       node->release();
       node->release();
@@ -3331,42 +3331,42 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag
     }
     nsIContent** clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr));
     nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->getFlags(), formattingElt->ns, formattingElt->name, clone, formattingElt->popName, formattingElt->attributes);
     formattingElt->dropAttributes();
     appendChildrenToNewParent(furthestBlock->node, clone);
     appendElement(clone, furthestBlock->node);
     removeFromListOfActiveFormattingElements(formattingEltListPos);
     insertIntoListOfActiveFormattingElements(formattingClone, bookmark);
-
+    MOZ_ASSERT(formattingEltStackPos < furthestBlockPos);
     removeFromStack(formattingEltStackPos);
     insertIntoStack(formattingClone, furthestBlockPos);
   }
   return true;
 }
 
 void 
 nsHtml5TreeBuilder::insertIntoStack(nsHtml5StackNode* node, int32_t position)
 {
-
-
+  MOZ_ASSERT(currentPtr + 1 < stack.length);
+  MOZ_ASSERT(position <= currentPtr + 1);
   if (position == currentPtr + 1) {
     push(node);
   } else {
     nsHtml5ArrayCopy::arraycopy(stack, position, position + 1, (currentPtr - position) + 1);
     currentPtr++;
     stack[position] = node;
   }
 }
 
 void 
 nsHtml5TreeBuilder::insertIntoListOfActiveFormattingElements(nsHtml5StackNode* formattingClone, int32_t bookmark)
 {
   formattingClone->retain();
-
+  MOZ_ASSERT(listPtr + 1 < listOfActiveFormattingElements.length);
   if (bookmark <= listPtr) {
     nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, bookmark, bookmark + 1, (listPtr - bookmark) + 1);
   }
   listPtr++;
   listOfActiveFormattingElements[bookmark] = formattingClone;
 }
 
 int32_t 
@@ -3453,19 +3453,19 @@ void
 nsHtml5TreeBuilder::addAttributesToHtml(nsHtml5HtmlAttributes* attributes)
 {
   addAttributesToElement(stack[0]->node, attributes);
 }
 
 void 
 nsHtml5TreeBuilder::pushHeadPointerOntoStack()
 {
-
-
-
+  MOZ_ASSERT(!!headPointer);
+  MOZ_ASSERT(!fragment);
+  MOZ_ASSERT(mode == NS_HTML5TREE_BUILDER_AFTER_HEAD);
 
   silentPush(new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, headPointer));
 }
 
 void 
 nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
 {
   if (listPtr == -1) {
@@ -3530,36 +3530,36 @@ nsHtml5TreeBuilder::isInStack(nsHtml5Sta
   }
   return false;
 }
 
 void 
 nsHtml5TreeBuilder::pop()
 {
   nsHtml5StackNode* node = stack[currentPtr];
-
+  MOZ_ASSERT(debugOnlyClearLastStackSlot());
   currentPtr--;
   elementPopped(node->ns, node->popName, node->node);
   node->release();
 }
 
 void 
 nsHtml5TreeBuilder::silentPop()
 {
   nsHtml5StackNode* node = stack[currentPtr];
-
+  MOZ_ASSERT(debugOnlyClearLastStackSlot());
   currentPtr--;
   node->release();
 }
 
 void 
 nsHtml5TreeBuilder::popOnEof()
 {
   nsHtml5StackNode* node = stack[currentPtr];
-
+  MOZ_ASSERT(debugOnlyClearLastStackSlot());
   currentPtr--;
   markMalformedIfScript(node->node);
   elementPopped(node->ns, node->popName, node->node);
   node->release();
 }
 
 void 
 nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes)
--- a/parser/html/nsHtml5TreeBuilder.h
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -126,18 +126,18 @@ class nsHtml5TreeBuilder : public nsAHtm
     void documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks);
     bool isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier);
     bool isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks);
     void closeTheCell(int32_t eltPos);
     int32_t findLastInTableScopeTdTh();
     void clearStackBackTo(int32_t eltPos);
     void resetTheInsertionMode();
     void implicitlyCloseP();
-    bool clearLastStackSlot();
-    bool clearLastListSlot();
+    bool debugOnlyClearLastStackSlot();
+    bool debugOnlyClearLastListSlot();
     void push(nsHtml5StackNode* node);
     void silentPush(nsHtml5StackNode* node);
     void append(nsHtml5StackNode* node);
     inline void insertMarker()
     {
       append(nullptr);
     }