Modernize coding style of HTMLTreeBuilder
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Jan 2015 16:31:49 +0000 (16:31 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Jan 2015 16:31:49 +0000 (16:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140032

Reviewed by Andreas Kling.

Changes include:
- Use references rather than pointers.
- Mark data members const that are fully set up in the constructor.
- Remove many unneeded includes and forward declarations.
- Fix conditionals to be consistent and correct.
- Merge some multi-line constructs into a single line.
- Update whatwg.org URLs; not sure we should keep these, though.
- Cut down on use of WTF_MAKE_NONCOPYABLE since for many classes it's
  impossible to copy anyway due to references, or harmless to copy.
- Made more things private.
- Initialize scalars in the class definition rather than each constructor.
- Use Ref/RefPtr instead of PassRefPtr.

* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::HTMLDocumentParser): Pass reference rather than pointer to
the context element.
(WebCore::HTMLDocumentParser::detach): Removed call to HTMLTreeBuilder::detach. This work
is instead done when the tree builder is destroyed.
(WebCore::HTMLDocumentParser::constructTreeFromHTMLToken): Pass reference rather than pointer.

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::uninitializedPositionValue1): Marked this inline because it's trivial. It was
probably getting inlined already.
(WebCore::isCaptionColOrColgroupTag): Format on a single line.
(WebCore::isTableBodyContextTag): Ditto.
(WebCore::isNonAnchorFormattingTag): Ditto.
(WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::ExternalCharacterTokenBuffer):
Take reference instead of pointer.
(WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeRemaining): Use makeString helper.
(WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::skipLeading): Tweak formatting.
(WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeLeading): Both of the above.
(WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::makeString): Added.
(WebCore::HTMLTreeBuilder::isParsingTemplateContents): Moved the body of this function here,
since it's only used inside the class.
(WebCore::HTMLTreeBuilder::isParsingFragmentOrTemplateContents): Ditto.
(WebCore::HTMLTreeBuilder::HTMLTreeBuilder): Get rid of dead code that handles a null context
element. The FIXME mentions a bug that is obsolete. Also reorder the data members to be a bit
more logical and set the new m_destructionProhibited to false at the end of the constructor,
to check if we accidentally destroy the tree builder while constructing it.
(WebCore::HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext): Updated to take
a reference and to let m_fragment get initialized in the class definition.
(WebCore::HTMLTreeBuilder::FragmentParsingContext::fragment): Moved this here since it's only
used inside the class.
(WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElement): Ditto.
(WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElementStackItem): Ditto.
(WebCore::HTMLTreeBuilder::takeScriptToProcess): Changed return type to RefPtr instead of
PassRefPtr. Added code to handle m_scriptToProcess of null, since reading the code at the
single call site makes it clear that it's not guaranteed to be non-null! Added destruction-
related assertions since this is a public function.
(WebCore::HTMLTreeBuilder::constructTree): Updated for reference rather than pointer. Also
added destruction-related assertions since this is a public function.
(WebCore::HTMLTreeBuilder::processToken): Updated to take a reference.
(WebCore::HTMLTreeBuilder::processDoctypeToken): Ditto.
(WebCore::HTMLTreeBuilder::processFakeStartTag): Ditto. Also take an rvalue reference for
the vector of attributes that we will put into the token.
(WebCore::HTMLTreeBuilder::processFakeEndTag): Ditto.
(WebCore::HTMLTreeBuilder::processFakePEndTagIfPInButtonScope): Ditto.
(WebCore::HTMLTreeBuilder::attributesForIsindexInput): Ditto.
(WebCore::HTMLTreeBuilder::processIsindexStartTagForInBody): Ditto.
(WebCore::isLi): Ditto.
(WebCore::isDdOrDt): Ditto.
(WebCore::HTMLTreeBuilder::processCloseWhenNestedTag): Changed loop to use reference
rather than pointer for never-null stackItem. Also use auto and a for loop to make the
loop easier to read.
(WebCore::createCaseMap): Tweaked formatting.
(WebCore::adjustAttributes): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInBody): Use reference instead of pointer.
Set insertion mode directly instead of using a setInsertionMode function.
(WebCore::HTMLTreeBuilder::processTemplateStartTag): Ditto.
(WebCore::HTMLTreeBuilder::processTemplateEndTag): Ditto.
(WebCore::HTMLTreeBuilder::processEndOfFileForInTemplateContents): Ditto.
(WebCore::HTMLTreeBuilder::processColgroupEndTagForInColumnGroup): Ditto.
(WebCore::HTMLTreeBuilder::closeTheCell): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
(WebCore::HTMLTreeBuilder::processStartTag): Ditto. Tweaked assertions, so that we
assert what state we are in before we fall through to each case, rather than asserting
inside each case. The per-case assertions were sort of excessive and repetitive and
even a bit hard to understand.
(WebCore::HTMLTreeBuilder::processHtmlStartTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processBodyEndTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processAnyOtherEndTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::callTheAdoptionAgency): Ditto.
(WebCore::HTMLTreeBuilder::resetInsertionModeAppropriately): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInTableBody): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInRow): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInCell): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processCaptionEndTagForInCaption): Ditto.
(WebCore::HTMLTreeBuilder::processTrEndTagForInRow): Ditto.
(WebCore::HTMLTreeBuilder::processTableEndTagForInTable): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInTable): Ditto.
(WebCore::HTMLTreeBuilder::processEndTag): Ditto.
(WebCore::HTMLTreeBuilder::processComment): Ditto.
(WebCore::HTMLTreeBuilder::processCharacter): Ditto.
(WebCore::HTMLTreeBuilder::insertPhoneNumberLink): Ditto.
(WebCore::HTMLTreeBuilder::processCharacterBuffer): Ditto.
(WebCore::HTMLTreeBuilder::processCharacterBufferForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processEndOfFile): Ditto.
(WebCore::HTMLTreeBuilder::defaultForInitial): Ditto.
(WebCore::HTMLTreeBuilder::defaultForBeforeHTML): Ditto.
(WebCore::HTMLTreeBuilder::defaultForBeforeHead): Ditto.
(WebCore::HTMLTreeBuilder::defaultForInHead): Ditto.
(WebCore::HTMLTreeBuilder::defaultForInHeadNoscript): Ditto.
(WebCore::HTMLTreeBuilder::defaultForAfterHead): Ditto.
(WebCore::HTMLTreeBuilder::defaultForInTableText): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInHead): Ditto.
(WebCore::HTMLTreeBuilder::processGenericRCDATAStartTag): Ditto.
(WebCore::HTMLTreeBuilder::processGenericRawTextStartTag): Ditto.
(WebCore::HTMLTreeBuilder::processScriptStartTag): Ditto.
(WebCore::HTMLTreeBuilder::adjustedCurrentStackItem): Made this return a reference.
(WebCore::HTMLTreeBuilder::shouldProcessTokenInForeignContent): More of the same.
(WebCore::HTMLTreeBuilder::processTokenInForeignContent): Ditto.
(WebCore::HTMLTreeBuilder::finished): Changed m_isAttached assertion to !m_destroyed.
Also updated the comment.
(WebCore::HTMLTreeBuilder::parseError): Marked this empty function inline.

* html/parser/HTMLTreeBuilder.h: Removed most includes and forward declarations.
Changed the phone number functions conditional to be correct. Removed a non-helpful
FIXME about assertions we really don't need. Removed unneeded use of the inline keyword,
changed types to references rather than pointer. Removed unneeded public insertionMode
and setInsertionMode functions. Both are things that are only done inside this class and
m_insertionMode can be accessed directly instead. Added a destructor that implements
the destruction assertions. Asserted !m_destroyed at the start of all the public functions.

* html/parser/TextDocumentParser.cpp:
(WebCore::TextDocumentParser::insertFakePreElement): Use reference rather than pointer.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177859 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/html/parser/HTMLDocumentParser.cpp
Source/WebCore/html/parser/HTMLTreeBuilder.cpp
Source/WebCore/html/parser/HTMLTreeBuilder.h
Source/WebCore/html/parser/TextDocumentParser.cpp

index 7787cd0..eca5a5e 100644 (file)
@@ -1,3 +1,137 @@
+2015-01-01  Darin Adler  <darin@apple.com>
+
+        Modernize coding style of HTMLTreeBuilder
+        https://bugs.webkit.org/show_bug.cgi?id=140032
+
+        Reviewed by Andreas Kling.
+
+        Changes include:
+        - Use references rather than pointers.
+        - Mark data members const that are fully set up in the constructor.
+        - Remove many unneeded includes and forward declarations.
+        - Fix conditionals to be consistent and correct.
+        - Merge some multi-line constructs into a single line.
+        - Update whatwg.org URLs; not sure we should keep these, though.
+        - Cut down on use of WTF_MAKE_NONCOPYABLE since for many classes it's
+          impossible to copy anyway due to references, or harmless to copy.
+        - Made more things private.
+        - Initialize scalars in the class definition rather than each constructor.
+        - Use Ref/RefPtr instead of PassRefPtr.
+
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::HTMLDocumentParser): Pass reference rather than pointer to
+        the context element.
+        (WebCore::HTMLDocumentParser::detach): Removed call to HTMLTreeBuilder::detach. This work
+        is instead done when the tree builder is destroyed.
+        (WebCore::HTMLDocumentParser::constructTreeFromHTMLToken): Pass reference rather than pointer.
+
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::uninitializedPositionValue1): Marked this inline because it's trivial. It was
+        probably getting inlined already.
+        (WebCore::isCaptionColOrColgroupTag): Format on a single line.
+        (WebCore::isTableBodyContextTag): Ditto.
+        (WebCore::isNonAnchorFormattingTag): Ditto.
+        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::ExternalCharacterTokenBuffer):
+        Take reference instead of pointer.
+        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeRemaining): Use makeString helper.
+        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::skipLeading): Tweak formatting.
+        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeLeading): Both of the above.
+        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::makeString): Added.
+        (WebCore::HTMLTreeBuilder::isParsingTemplateContents): Moved the body of this function here,
+        since it's only used inside the class.
+        (WebCore::HTMLTreeBuilder::isParsingFragmentOrTemplateContents): Ditto.
+        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder): Get rid of dead code that handles a null context
+        element. The FIXME mentions a bug that is obsolete. Also reorder the data members to be a bit
+        more logical and set the new m_destructionProhibited to false at the end of the constructor,
+        to check if we accidentally destroy the tree builder while constructing it.
+        (WebCore::HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext): Updated to take
+        a reference and to let m_fragment get initialized in the class definition.
+        (WebCore::HTMLTreeBuilder::FragmentParsingContext::fragment): Moved this here since it's only
+        used inside the class.
+        (WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElement): Ditto.
+        (WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElementStackItem): Ditto.
+        (WebCore::HTMLTreeBuilder::takeScriptToProcess): Changed return type to RefPtr instead of
+        PassRefPtr. Added code to handle m_scriptToProcess of null, since reading the code at the
+        single call site makes it clear that it's not guaranteed to be non-null! Added destruction-
+        related assertions since this is a public function.
+        (WebCore::HTMLTreeBuilder::constructTree): Updated for reference rather than pointer. Also
+        added destruction-related assertions since this is a public function.
+        (WebCore::HTMLTreeBuilder::processToken): Updated to take a reference.
+        (WebCore::HTMLTreeBuilder::processDoctypeToken): Ditto.
+        (WebCore::HTMLTreeBuilder::processFakeStartTag): Ditto. Also take an rvalue reference for
+        the vector of attributes that we will put into the token.
+        (WebCore::HTMLTreeBuilder::processFakeEndTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processFakePEndTagIfPInButtonScope): Ditto.
+        (WebCore::HTMLTreeBuilder::attributesForIsindexInput): Ditto.
+        (WebCore::HTMLTreeBuilder::processIsindexStartTagForInBody): Ditto.
+        (WebCore::isLi): Ditto.
+        (WebCore::isDdOrDt): Ditto.
+        (WebCore::HTMLTreeBuilder::processCloseWhenNestedTag): Changed loop to use reference
+        rather than pointer for never-null stackItem. Also use auto and a for loop to make the
+        loop easier to read.
+        (WebCore::createCaseMap): Tweaked formatting.
+        (WebCore::adjustAttributes): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTagForInBody): Use reference instead of pointer.
+        Set insertion mode directly instead of using a setInsertionMode function.
+        (WebCore::HTMLTreeBuilder::processTemplateStartTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processTemplateEndTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndOfFileForInTemplateContents): Ditto.
+        (WebCore::HTMLTreeBuilder::processColgroupEndTagForInColumnGroup): Ditto.
+        (WebCore::HTMLTreeBuilder::closeTheCell): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTag): Ditto. Tweaked assertions, so that we
+        assert what state we are in before we fall through to each case, rather than asserting
+        inside each case. The per-case assertions were sort of excessive and repetitive and
+        even a bit hard to understand.
+        (WebCore::HTMLTreeBuilder::processHtmlStartTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processBodyEndTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processAnyOtherEndTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::callTheAdoptionAgency): Ditto.
+        (WebCore::HTMLTreeBuilder::resetInsertionModeAppropriately): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInTableBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInRow): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInCell): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processCaptionEndTagForInCaption): Ditto.
+        (WebCore::HTMLTreeBuilder::processTrEndTagForInRow): Ditto.
+        (WebCore::HTMLTreeBuilder::processTableEndTagForInTable): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInTable): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processComment): Ditto.
+        (WebCore::HTMLTreeBuilder::processCharacter): Ditto.
+        (WebCore::HTMLTreeBuilder::insertPhoneNumberLink): Ditto.
+        (WebCore::HTMLTreeBuilder::processCharacterBuffer): Ditto.
+        (WebCore::HTMLTreeBuilder::processCharacterBufferForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndOfFile): Ditto.
+        (WebCore::HTMLTreeBuilder::defaultForInitial): Ditto.
+        (WebCore::HTMLTreeBuilder::defaultForBeforeHTML): Ditto.
+        (WebCore::HTMLTreeBuilder::defaultForBeforeHead): Ditto.
+        (WebCore::HTMLTreeBuilder::defaultForInHead): Ditto.
+        (WebCore::HTMLTreeBuilder::defaultForInHeadNoscript): Ditto.
+        (WebCore::HTMLTreeBuilder::defaultForAfterHead): Ditto.
+        (WebCore::HTMLTreeBuilder::defaultForInTableText): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTagForInHead): Ditto.
+        (WebCore::HTMLTreeBuilder::processGenericRCDATAStartTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processGenericRawTextStartTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processScriptStartTag): Ditto.
+        (WebCore::HTMLTreeBuilder::adjustedCurrentStackItem): Made this return a reference.
+        (WebCore::HTMLTreeBuilder::shouldProcessTokenInForeignContent): More of the same.
+        (WebCore::HTMLTreeBuilder::processTokenInForeignContent): Ditto.
+        (WebCore::HTMLTreeBuilder::finished): Changed m_isAttached assertion to !m_destroyed.
+        Also updated the comment.
+        (WebCore::HTMLTreeBuilder::parseError): Marked this empty function inline.
+
+        * html/parser/HTMLTreeBuilder.h: Removed most includes and forward declarations.
+        Changed the phone number functions conditional to be correct. Removed a non-helpful
+        FIXME about assertions we really don't need. Removed unneeded use of the inline keyword,
+        changed types to references rather than pointer. Removed unneeded public insertionMode
+        and setInsertionMode functions. Both are things that are only done inside this class and
+        m_insertionMode can be accessed directly instead. Added a destructor that implements
+        the destruction assertions. Asserted !m_destroyed at the start of all the public functions.
+
+        * html/parser/TextDocumentParser.cpp:
+        (WebCore::TextDocumentParser::insertFakePreElement): Use reference rather than pointer.
+
 2015-01-02  Manuel Rego Casasnovas  <rego@igalia.com>
 
         [CSS Grid Layout] Remove stack from grid-auto-flow syntax
index e0fb5fc..20cff5c 100644 (file)
@@ -92,7 +92,7 @@ HTMLDocumentParser::HTMLDocumentParser(DocumentFragment& fragment, Element* cont
     , m_options(fragment.document())
     , m_token(std::make_unique<HTMLToken>())
     , m_tokenizer(std::make_unique<HTMLTokenizer>(m_options))
-    , m_treeBuilder(std::make_unique<HTMLTreeBuilder>(*this, fragment, contextElement, this->parserContentPolicy(), m_options))
+    , m_treeBuilder(std::make_unique<HTMLTreeBuilder>(*this, fragment, *contextElement, this->parserContentPolicy(), m_options))
     , m_xssAuditorDelegate(fragment.document())
     , m_endWasDelayed(false)
     , m_haveBackgroundParser(false)
@@ -118,7 +118,6 @@ void HTMLDocumentParser::detach()
 
     if (m_scriptRunner)
         m_scriptRunner->detach();
-    m_treeBuilder->detach();
     // FIXME: It seems wrong that we would have a preload scanner here.
     // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do.
     m_preloadScanner = nullptr;
@@ -349,7 +348,7 @@ void HTMLDocumentParser::constructTreeFromHTMLToken(HTMLToken& rawToken)
     if (rawToken.type() != HTMLToken::Character)
         rawToken.clear();
 
-    m_treeBuilder->constructTree(&token);
+    m_treeBuilder->constructTree(token);
 
     if (!rawToken.isUninitialized()) {
         ASSERT(rawToken.type() == HTMLToken::Character);
index 19588ae..eed6461 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "DocumentFragment.h"
 #include "HTMLDocument.h"
 #include "HTMLDocumentParser.h"
-#include "HTMLFormControlElement.h"
 #include "HTMLFormElement.h"
 #include "HTMLOptGroupElement.h"
-#include "HTMLOptionElement.h"
 #include "HTMLParserIdioms.h"
-#include "HTMLTableElement.h"
-#include "HTMLTemplateElement.h"
 #include "LocalizedStrings.h"
 #include "NotImplemented.h"
 #include "XLinkNames.h"
 #include "XMLNSNames.h"
 #include "XMLNames.h"
-#include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/unicode/CharacterNames.h>
 
-#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
 #include "TelephoneNumberDetector.h"
 #endif
 
@@ -63,7 +58,7 @@ inline bool isHTMLSpaceOrReplacementCharacter(UChar character)
 
 }
 
-static TextPosition uninitializedPositionValue1()
+static inline TextPosition uninitializedPositionValue1()
 {
     return TextPosition(OrdinalNumber::fromOneBasedInt(-1), OrdinalNumber::first());
 }
@@ -90,9 +85,7 @@ static bool isNumberedHeaderTag(const AtomicString& tagName)
 
 static bool isCaptionColOrColgroupTag(const AtomicString& tagName)
 {
-    return tagName == captionTag
-        || tagName == colTag
-        || tagName == colgroupTag;
+    return tagName == captionTag || tagName == colTag || tagName == colgroupTag;
 }
 
 static bool isTableCellContextTag(const AtomicString& tagName)
@@ -102,9 +95,7 @@ static bool isTableCellContextTag(const AtomicString& tagName)
 
 static bool isTableBodyContextTag(const AtomicString& tagName)
 {
-    return tagName == tbodyTag
-        || tagName == tfootTag
-        || tagName == theadTag;
+    return tagName == tbodyTag || tagName == tfootTag || tagName == theadTag;
 }
 
 static bool isNonAnchorNonNobrFormattingTag(const AtomicString& tagName)
@@ -125,29 +116,27 @@ static bool isNonAnchorNonNobrFormattingTag(const AtomicString& tagName)
 
 static bool isNonAnchorFormattingTag(const AtomicString& tagName)
 {
-    return tagName == nobrTag
-        || isNonAnchorNonNobrFormattingTag(tagName);
+    return tagName == nobrTag || isNonAnchorNonNobrFormattingTag(tagName);
 }
 
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#formatting
+// https://html.spec.whatwg.org/multipage/syntax.html#formatting
 static bool isFormattingTag(const AtomicString& tagName)
 {
     return tagName == aTag || isNonAnchorFormattingTag(tagName);
 }
 
 class HTMLTreeBuilder::ExternalCharacterTokenBuffer {
-    WTF_MAKE_NONCOPYABLE(ExternalCharacterTokenBuffer);
 public:
-    explicit ExternalCharacterTokenBuffer(AtomicHTMLToken* token)
-        : m_text(token->characters(), token->charactersLength())
-        , m_isAll8BitData(token->isAll8BitData())
+    explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token)
+        : m_text(token.characters(), token.charactersLength())
+        , m_isAll8BitData(token.isAll8BitData())
     {
         ASSERT(!isEmpty());
     }
 
     explicit ExternalCharacterTokenBuffer(const String& string)
         : m_text(string)
-        , m_isAll8BitData(m_text.length() && m_text.is8Bit())
+        , m_isAll8BitData(m_text.is8Bit())
     {
         ASSERT(!isEmpty());
     }
@@ -185,11 +174,7 @@ public:
 
     String takeRemaining()
     {
-        String result;
-        if (m_text.is8Bit() || !isAll8BitData())
-            result = m_text.toString();
-        else
-            result = String::make8BitFrom16BitSource(m_text.characters16(), m_text.length());
+        String result = makeString(m_text);
         m_text = StringView();
         return result;
     }
@@ -221,8 +206,7 @@ public:
     }
 
 private:
-    template<bool characterPredicate(UChar)>
-    void skipLeading()
+    template<bool characterPredicate(UChar)> void skipLeading()
     {
         ASSERT(!isEmpty());
         while (characterPredicate(m_text[0])) {
@@ -232,122 +216,124 @@ private:
         }
     }
 
-    template<bool characterPredicate(UChar)>
-    String takeLeading()
+    template<bool characterPredicate(UChar)> String takeLeading()
     {
         ASSERT(!isEmpty());
         StringView start = m_text;
         skipLeading<characterPredicate>();
         if (start.length() == m_text.length())
             return String();
-        StringView leading = start.substring(0, start.length() - m_text.length());
-        if (leading.is8Bit() || !isAll8BitData())
-            return leading.toString();
-        return String::make8BitFrom16BitSource(leading.characters16(), leading.length());
+        return makeString(start.substring(0, start.length() - m_text.length()));
+    }
+
+    String makeString(StringView stringView) const
+    {
+        if (stringView.is8Bit() || !isAll8BitData())
+            return stringView.toString();
+        return String::make8BitFrom16BitSource(stringView.characters16(), stringView.length());
     }
 
     StringView m_text;
     bool m_isAll8BitData;
 };
 
-
-HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser& parser, HTMLDocument& document, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
-    : m_framesetOk(true)
-#ifndef NDEBUG
-    , m_isAttached(true)
+inline bool HTMLTreeBuilder::isParsingTemplateContents() const
+{
+#if ENABLE(TEMPLATE_ELEMENT)
+    return m_tree.openElements()->hasTemplateInHTMLScope();
+#else
+    return false;
 #endif
+}
+
+inline bool HTMLTreeBuilder::isParsingFragmentOrTemplateContents() const
+{
+    return isParsingFragment() || isParsingTemplateContents();
+}
+
+HTMLTreeBuilder::HTMLTreeBuilder(const HTMLDocumentParser& parser, HTMLDocument& document, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
+    : m_parser(parser)
+    , m_options(options)
     , m_tree(document, parserContentPolicy, options.maximumDOMTreeDepth)
-    , m_insertionMode(InsertionMode::Initial)
-    , m_originalInsertionMode(InsertionMode::Initial)
-    , m_shouldSkipLeadingNewline(false)
-    , m_parser(parser)
     , m_scriptToProcessStartPosition(uninitializedPositionValue1())
-    , m_options(options)
 {
+#if !ASSERT_DISABLED
+    m_destructionProhibited = false;
+#endif
 }
 
-// FIXME: Member variables should be grouped into self-initializing structs to
-// minimize code duplication between these constructors.
-HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser& parser, DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
-    : m_framesetOk(true)
-#ifndef NDEBUG
-    , m_isAttached(true)
-#endif
+HTMLTreeBuilder::HTMLTreeBuilder(const HTMLDocumentParser& parser, DocumentFragment& fragment, Element& contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
+    : m_parser(parser)
+    , m_options(options)
     , m_fragmentContext(fragment, contextElement)
     , m_tree(fragment, parserContentPolicy, options.maximumDOMTreeDepth)
-    , m_insertionMode(InsertionMode::Initial)
-    , m_originalInsertionMode(InsertionMode::Initial)
-    , m_shouldSkipLeadingNewline(false)
-    , m_parser(parser)
     , m_scriptToProcessStartPosition(uninitializedPositionValue1())
-    , m_options(options)
 {
     ASSERT(isMainThread());
-    // FIXME: This assertion will become invalid if <http://webkit.org/b/60316> is fixed.
-    ASSERT(contextElement);
-    if (contextElement) {
-        // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
-        // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
-        // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
-        // and instead use the DocumentFragment as a root node.
-        m_tree.openElements()->pushRootNode(HTMLStackItem::create(&fragment, HTMLStackItem::ItemForDocumentFragmentNode));
+
+    // https://html.spec.whatwg.org/multipage/syntax.html#parsing-html-fragments
+    // For efficiency, we skip step 5 ("Let root be a new html element with no attributes") and instead use the DocumentFragment as a root node.
+    m_tree.openElements()->pushRootNode(HTMLStackItem::create(&fragment, HTMLStackItem::ItemForDocumentFragmentNode));
 
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (contextElement->hasTagName(templateTag))
-            m_templateInsertionModes.append(InsertionMode::TemplateContents);
+    if (contextElement.hasTagName(templateTag))
+        m_templateInsertionModes.append(InsertionMode::TemplateContents);
 #endif
 
-        resetInsertionModeAppropriately();
-        m_tree.setForm(!contextElement || is<HTMLFormElement>(*contextElement) ? downcast<HTMLFormElement>(contextElement) : HTMLFormElement::findClosestFormAncestor(*contextElement));
-    }
-}
+    resetInsertionModeAppropriately();
 
-HTMLTreeBuilder::~HTMLTreeBuilder()
-{
-}
+    m_tree.setForm(is<HTMLFormElement>(contextElement) ? &downcast<HTMLFormElement>(contextElement) : HTMLFormElement::findClosestFormAncestor(contextElement));
 
-void HTMLTreeBuilder::detach()
-{
-#ifndef NDEBUG
-    // This call makes little sense in fragment mode, but for consistency
-    // DocumentParser expects detach() to always be called before it's destroyed.
-    m_isAttached = false;
+#if !ASSERT_DISABLED
+    m_destructionProhibited = false;
 #endif
-    // HTMLConstructionSite might be on the callstack when detach() is called
-    // otherwise we'd just call m_tree.clear() here instead.
-    m_tree.detach();
 }
 
 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext()
-    : m_fragment(0)
 {
 }
 
-HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment& fragment, Element* contextElement)
+HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment& fragment, Element& contextElement)
     : m_fragment(&fragment)
 {
     ASSERT(!fragment.hasChildNodes());
-    m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackItem::ItemForContextElement);
+    m_contextElementStackItem = HTMLStackItem::create(&contextElement, HTMLStackItem::ItemForContextElement);
 }
 
-HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
+inline Element& HTMLTreeBuilder::FragmentParsingContext::contextElement() const
 {
+    return *contextElementStackItem().element();
 }
 
-PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
+inline HTMLStackItem& HTMLTreeBuilder::FragmentParsingContext::contextElementStackItem() const
 {
-    ASSERT(m_scriptToProcess);
+    ASSERT(m_fragment);
+    return *m_contextElementStackItem;
+}
+
+RefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
+{
+    ASSERT(!m_destroyed);
+
+    if (!m_scriptToProcess)
+        return nullptr;
+
     // Unpause ourselves, callers may pause us again when processing the script.
-    // The HTML5 spec is written as though scripts are executed inside the tree
-    // builder.  We pause the parser to exit the tree builder, and then resume
-    // before running scripts.
+    // The HTML5 spec is written as though scripts are executed inside the tree builder.
+    // We pause the parser to exit the tree builder, and then resume before running scripts.
     scriptStartPosition = m_scriptToProcessStartPosition;
     m_scriptToProcessStartPosition = uninitializedPositionValue1();
-    return m_scriptToProcess.release();
+    return WTF::move(m_scriptToProcess);
 }
 
-void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token)
+void HTMLTreeBuilder::constructTree(AtomicHTMLToken& token)
 {
+#if !ASSERT_DISABLED
+    ASSERT(!m_destroyed);
+    ASSERT(!m_destructionProhibited);
+    m_destructionProhibited = true;
+#endif
+
     if (shouldProcessTokenInForeignContent(token))
         processTokenInForeignContent(token);
     else
@@ -355,7 +341,7 @@ void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token)
 
     if (m_parser.tokenizer()) {
         bool inForeignContent = !m_tree.isEmpty()
-            && !adjustedCurrentStackItem()->isInHTMLNamespace()
+            && !adjustedCurrentStackItem().isInHTMLNamespace()
             && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem())
             && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem());
 
@@ -363,13 +349,17 @@ void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token)
         m_parser.tokenizer()->setShouldAllowCDATA(inForeignContent);
     }
 
+#if !ASSERT_DISABLED
+    m_destructionProhibited = false;
+#endif
+
     m_tree.executeQueuedTasks();
-    // We might be detached now.
+    // The tree builder might have been destroyed as an indirect result of executing the queued tasks.
 }
 
-void HTMLTreeBuilder::processToken(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processToken(AtomicHTMLToken& token)
 {
-    switch (token->type()) {
+    switch (token.type()) {
     case HTMLToken::Uninitialized:
         ASSERT_NOT_REACHED();
         break;
@@ -399,12 +389,12 @@ void HTMLTreeBuilder::processToken(AtomicHTMLToken* token)
     }
 }
 
-void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::DOCTYPE);
+    ASSERT(token.type() == HTMLToken::DOCTYPE);
     if (m_insertionMode == InsertionMode::Initial) {
-        m_tree.insertDoctype(token);
-        setInsertionMode(InsertionMode::BeforeHTML);
+        m_tree.insertDoctype(&token);
+        m_insertionMode = InsertionMode::BeforeHTML;
         return;
     }
     if (m_insertionMode == InsertionMode::InTableText) {
@@ -415,17 +405,17 @@ void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken* token)
     parseError(token);
 }
 
-void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, const Vector<Attribute>& attributes)
+void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, Vector<Attribute>&& attributes)
 {
     // FIXME: We'll need a fancier conversion than just "localName" for SVG/MathML tags.
-    AtomicHTMLToken fakeToken(HTMLToken::StartTag, tagName.localName(), attributes);
-    processStartTag(&fakeToken);
+    AtomicHTMLToken fakeToken(HTMLToken::StartTag, tagName.localName(), WTF::move(attributes));
+    processStartTag(fakeToken);
 }
 
 void HTMLTreeBuilder::processFakeEndTag(const AtomicString& tagName)
 {
     AtomicHTMLToken fakeToken(HTMLToken::EndTag, tagName);
-    processEndTag(&fakeToken);
+    processEndTag(fakeToken);
 }
 
 void HTMLTreeBuilder::processFakeEndTag(const QualifiedName& tagName)
@@ -446,12 +436,12 @@ void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
     if (!m_tree.openElements()->inButtonScope(pTag.localName()))
         return;
     AtomicHTMLToken endP(HTMLToken::EndTag, pTag.localName());
-    processEndTag(&endP);
+    processEndTag(endP);
 }
 
-Vector<Attribute> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken* token)
+Vector<Attribute> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken& token)
 {
-    Vector<Attribute> attributes = token->attributes();
+    Vector<Attribute> attributes = token.attributes();
     for (int i = attributes.size() - 1; i >= 0; --i) {
         const QualifiedName& name = attributes.at(i).name();
         if (name.matches(nameAttr) || name.matches(actionAttr) || name.matches(promptAttr))
@@ -462,21 +452,21 @@ Vector<Attribute> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken* to
     return attributes;
 }
 
-void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::StartTag);
-    ASSERT(token->name() == isindexTag);
+    ASSERT(token.type() == HTMLToken::StartTag);
+    ASSERT(token.name() == isindexTag);
     parseError(token);
     if (m_tree.form() && !isParsingTemplateContents())
         return;
     notImplemented(); // Acknowledge self-closing flag
     processFakeStartTag(formTag);
-    Attribute* actionAttribute = token->getAttributeItem(actionAttr);
+    Attribute* actionAttribute = token.getAttributeItem(actionAttr);
     if (actionAttribute)
         m_tree.form()->setAttribute(actionAttr, actionAttribute->value());
     processFakeStartTag(hrTag);
     processFakeStartTag(labelTag);
-    Attribute* promptAttribute = token->getAttributeItem(promptAttr);
+    Attribute* promptAttribute = token.getAttributeItem(promptAttr);
     if (promptAttribute)
         processFakeCharacters(promptAttribute->value());
     else
@@ -490,41 +480,36 @@ void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
 
 namespace {
 
-bool isLi(const HTMLStackItem* item)
+bool isLi(const HTMLStackItem& item)
 {
-    return item->hasTagName(liTag);
+    return item.hasTagName(liTag);
 }
 
-bool isDdOrDt(const HTMLStackItem* item)
+bool isDdOrDt(const HTMLStackItem& item)
 {
-    return item->hasTagName(ddTag)
-        || item->hasTagName(dtTag);
+    return item.hasTagName(ddTag) || item.hasTagName(dtTag);
 }
 
 }
 
-template <bool shouldClose(const HTMLStackItem*)>
-void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token)
+template <bool shouldClose(const HTMLStackItem&)> void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken& token)
 {
     m_framesetOk = false;
-    HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
-    while (1) {
-        RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
-        if (shouldClose(item.get())) {
-            ASSERT(item->isElementNode());
-            processFakeEndTag(item->localName());
+    for (auto* nodeRecord = m_tree.openElements()->topRecord(); ; nodeRecord = nodeRecord->next()) {
+        HTMLStackItem& item = *nodeRecord->stackItem();
+        if (shouldClose(item)) {
+            ASSERT(item.isElementNode());
+            processFakeEndTag(item.localName());
             break;
         }
-        if (item->isSpecialNode() && !item->hasTagName(addressTag) && !item->hasTagName(divTag) && !item->hasTagName(pTag))
+        if (item.isSpecialNode() && !item.hasTagName(addressTag) && !item.hasTagName(divTag) && !item.hasTagName(pTag))
             break;
-        nodeRecord = nodeRecord->next();
     }
     processFakePEndTagIfPInButtonScope();
-    m_tree.insertHTMLElement(token);
+    m_tree.insertHTMLElement(&token);
 }
 
-template <typename TableQualifiedName>
-static HashMap<AtomicString, QualifiedName> createCaseMap(const TableQualifiedName* const names[], unsigned length)
+template <typename TableQualifiedName> static HashMap<AtomicString, QualifiedName> createCaseMap(const TableQualifiedName* const names[], unsigned length)
 {
     HashMap<AtomicString, QualifiedName> map;
     for (unsigned i = 0; i < length; ++i) {
@@ -555,8 +540,7 @@ static inline void adjustAttributes(HashMap<AtomicString, QualifiedName>& map, A
     }
 }
 
-template<const QualifiedName* const* attributesTable(), unsigned attributesTableLength>
-static void adjustAttributes(AtomicHTMLToken& token)
+template<const QualifiedName* const* attributesTable(), unsigned attributesTableLength> static void adjustAttributes(AtomicHTMLToken& token)
 {
     static NeverDestroyed<HashMap<AtomicString, QualifiedName>> map = createCaseMap(attributesTable(), attributesTableLength);
     adjustAttributes(map, token);
@@ -600,28 +584,28 @@ static void adjustForeignAttributes(AtomicHTMLToken& token)
     adjustAttributes(map, token);
 }
 
-void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::StartTag);
-    if (token->name() == htmlTag) {
+    ASSERT(token.type() == HTMLToken::StartTag);
+    if (token.name() == htmlTag) {
         processHtmlStartTagForInBody(token);
         return;
     }
-    if (token->name() == baseTag
-        || token->name() == basefontTag
-        || token->name() == bgsoundTag
-        || token->name() == commandTag
-        || token->name() == linkTag
-        || token->name() == metaTag
-        || token->name() == noframesTag
-        || token->name() == scriptTag
-        || token->name() == styleTag
-        || token->name() == titleTag) {
+    if (token.name() == baseTag
+        || token.name() == basefontTag
+        || token.name() == bgsoundTag
+        || token.name() == commandTag
+        || token.name() == linkTag
+        || token.name() == metaTag
+        || token.name() == noframesTag
+        || token.name() == scriptTag
+        || token.name() == styleTag
+        || token.name() == titleTag) {
         bool didProcess = processStartTagForInHead(token);
         ASSERT_UNUSED(didProcess, didProcess);
         return;
     }
-    if (token->name() == bodyTag) {
+    if (token.name() == bodyTag) {
         parseError(token);
         bool fragmentOrTemplateCase = !m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement();
 #if ENABLE(TEMPLATE_ELEMENT)
@@ -632,10 +616,10 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
             return;
         }
         m_framesetOk = false;
-        m_tree.insertHTMLBodyStartTagInBody(token);
+        m_tree.insertHTMLBodyStartTagInBody(&token);
         return;
     }
-    if (token->name() == framesetTag) {
+    if (token.name() == framesetTag) {
         parseError(token);
         if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement()) {
             ASSERT(isParsingFragmentOrTemplateContents());
@@ -647,78 +631,78 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
         m_tree.openElements()->popUntil(m_tree.openElements()->bodyElement());
         m_tree.openElements()->popHTMLBodyElement();
         ASSERT(m_tree.openElements()->top() == m_tree.openElements()->htmlElement());
-        m_tree.insertHTMLElement(token);
-        setInsertionMode(InsertionMode::InFrameset);
-        return;
-    }
-    if (token->name() == addressTag
-        || token->name() == articleTag
-        || token->name() == asideTag
-        || token->name() == blockquoteTag
-        || token->name() == centerTag
-        || token->name() == detailsTag
-        || token->name() == dirTag
-        || token->name() == divTag
-        || token->name() == dlTag
-        || token->name() == fieldsetTag
-        || token->name() == figcaptionTag
-        || token->name() == figureTag
-        || token->name() == footerTag
-        || token->name() == headerTag
-        || token->name() == hgroupTag
-        || token->name() == mainTag
-        || token->name() == menuTag
-        || token->name() == navTag
-        || token->name() == olTag
-        || token->name() == pTag
-        || token->name() == sectionTag
-        || token->name() == summaryTag
-        || token->name() == ulTag) {
+        m_tree.insertHTMLElement(&token);
+        m_insertionMode = InsertionMode::InFrameset;
+        return;
+    }
+    if (token.name() == addressTag
+        || token.name() == articleTag
+        || token.name() == asideTag
+        || token.name() == blockquoteTag
+        || token.name() == centerTag
+        || token.name() == detailsTag
+        || token.name() == dirTag
+        || token.name() == divTag
+        || token.name() == dlTag
+        || token.name() == fieldsetTag
+        || token.name() == figcaptionTag
+        || token.name() == figureTag
+        || token.name() == footerTag
+        || token.name() == headerTag
+        || token.name() == hgroupTag
+        || token.name() == mainTag
+        || token.name() == menuTag
+        || token.name() == navTag
+        || token.name() == olTag
+        || token.name() == pTag
+        || token.name() == sectionTag
+        || token.name() == summaryTag
+        || token.name() == ulTag) {
         processFakePEndTagIfPInButtonScope();
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         return;
     }
-    if (isNumberedHeaderTag(token->name())) {
+    if (isNumberedHeaderTag(token.name())) {
         processFakePEndTagIfPInButtonScope();
         if (m_tree.currentStackItem()->isNumberedHeaderElement()) {
             parseError(token);
             m_tree.openElements()->pop();
         }
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         return;
     }
-    if (token->name() == preTag || token->name() == listingTag) {
+    if (token.name() == preTag || token.name() == listingTag) {
         processFakePEndTagIfPInButtonScope();
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         m_shouldSkipLeadingNewline = true;
         m_framesetOk = false;
         return;
     }
-    if (token->name() == formTag) {
+    if (token.name() == formTag) {
         if (m_tree.form() && !isParsingTemplateContents()) {
             parseError(token);
             return;
         }
         processFakePEndTagIfPInButtonScope();
-        m_tree.insertHTMLFormElement(token);
+        m_tree.insertHTMLFormElement(&token);
         return;
     }
-    if (token->name() == liTag) {
+    if (token.name() == liTag) {
         processCloseWhenNestedTag<isLi>(token);
         return;
     }
-    if (token->name() == ddTag || token->name() == dtTag) {
+    if (token.name() == ddTag || token.name() == dtTag) {
         processCloseWhenNestedTag<isDdOrDt>(token);
         return;
     }
-    if (token->name() == plaintextTag) {
+    if (token.name() == plaintextTag) {
         processFakePEndTagIfPInButtonScope();
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         if (m_parser.tokenizer())
             m_parser.tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
         return;
     }
-    if (token->name() == buttonTag) {
+    if (token.name() == buttonTag) {
         if (m_tree.openElements()->inScope(buttonTag)) {
             parseError(token);
             processFakeEndTag(buttonTag);
@@ -726,11 +710,11 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
             return;
         }
         m_tree.reconstructTheActiveFormattingElements();
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         m_framesetOk = false;
         return;
     }
-    if (token->name() == aTag) {
+    if (token.name() == aTag) {
         Element* activeATag = m_tree.activeFormattingElements()->closestElementInScopeWithName(aTag.localName());
         if (activeATag) {
             parseError(token);
@@ -740,121 +724,117 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
                 m_tree.openElements()->remove(activeATag);
         }
         m_tree.reconstructTheActiveFormattingElements();
-        m_tree.insertFormattingElement(token);
+        m_tree.insertFormattingElement(&token);
         return;
     }
-    if (isNonAnchorNonNobrFormattingTag(token->name())) {
+    if (isNonAnchorNonNobrFormattingTag(token.name())) {
         m_tree.reconstructTheActiveFormattingElements();
-        m_tree.insertFormattingElement(token);
+        m_tree.insertFormattingElement(&token);
         return;
     }
-    if (token->name() == nobrTag) {
+    if (token.name() == nobrTag) {
         m_tree.reconstructTheActiveFormattingElements();
         if (m_tree.openElements()->inScope(nobrTag)) {
             parseError(token);
             processFakeEndTag(nobrTag);
             m_tree.reconstructTheActiveFormattingElements();
         }
-        m_tree.insertFormattingElement(token);
+        m_tree.insertFormattingElement(&token);
         return;
     }
-    if (token->name() == appletTag
-        || token->name() == embedTag
-        || token->name() == objectTag) {
+    if (token.name() == appletTag || token.name() == embedTag || token.name() == objectTag) {
         if (!pluginContentIsAllowed(m_tree.parserContentPolicy()))
             return;
     }
-    if (token->name() == appletTag
-        || token->name() == marqueeTag
-        || token->name() == objectTag) {
+    if (token.name() == appletTag || token.name() == marqueeTag || token.name() == objectTag) {
         m_tree.reconstructTheActiveFormattingElements();
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         m_tree.activeFormattingElements()->appendMarker();
         m_framesetOk = false;
         return;
     }
-    if (token->name() == tableTag) {
+    if (token.name() == tableTag) {
         if (!m_tree.inQuirksMode() && m_tree.openElements()->inButtonScope(pTag))
             processFakeEndTag(pTag);
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         m_framesetOk = false;
-        setInsertionMode(InsertionMode::InTable);
+        m_insertionMode = InsertionMode::InTable;
         return;
     }
-    if (token->name() == imageTag) {
+    if (token.name() == imageTag) {
         parseError(token);
         // Apparently we're not supposed to ask.
-        token->setName(imgTag.localName());
+        token.setName(imgTag.localName());
         // Note the fall through to the imgTag handling below!
     }
-    if (token->name() == areaTag
-        || token->name() == brTag
-        || token->name() == embedTag
-        || token->name() == imgTag
-        || token->name() == keygenTag
-        || token->name() == wbrTag) {
+    if (token.name() == areaTag
+        || token.name() == brTag
+        || token.name() == embedTag
+        || token.name() == imgTag
+        || token.name() == keygenTag
+        || token.name() == wbrTag) {
         m_tree.reconstructTheActiveFormattingElements();
-        m_tree.insertSelfClosingHTMLElement(token);
+        m_tree.insertSelfClosingHTMLElement(&token);
         m_framesetOk = false;
         return;
     }
-    if (token->name() == inputTag) {
-        Attribute* typeAttribute = token->getAttributeItem(typeAttr);
+    if (token.name() == inputTag) {
+        Attribute* typeAttribute = token.getAttributeItem(typeAttr);
         m_tree.reconstructTheActiveFormattingElements();
-        m_tree.insertSelfClosingHTMLElement(token);
+        m_tree.insertSelfClosingHTMLElement(&token);
         if (!typeAttribute || !equalIgnoringCase(typeAttribute->value(), "hidden"))
             m_framesetOk = false;
         return;
     }
-    if (token->name() == paramTag
-        || token->name() == sourceTag
-        || token->name() == trackTag) {
-        m_tree.insertSelfClosingHTMLElement(token);
+    if (token.name() == paramTag
+        || token.name() == sourceTag
+        || token.name() == trackTag) {
+        m_tree.insertSelfClosingHTMLElement(&token);
         return;
     }
-    if (token->name() == hrTag) {
+    if (token.name() == hrTag) {
         processFakePEndTagIfPInButtonScope();
-        m_tree.insertSelfClosingHTMLElement(token);
+        m_tree.insertSelfClosingHTMLElement(&token);
         m_framesetOk = false;
         return;
     }
-    if (token->name() == isindexTag) {
+    if (token.name() == isindexTag) {
         processIsindexStartTagForInBody(token);
         return;
     }
-    if (token->name() == textareaTag) {
-        m_tree.insertHTMLElement(token);
+    if (token.name() == textareaTag) {
+        m_tree.insertHTMLElement(&token);
         m_shouldSkipLeadingNewline = true;
         if (m_parser.tokenizer())
             m_parser.tokenizer()->setState(HTMLTokenizer::RCDATAState);
         m_originalInsertionMode = m_insertionMode;
         m_framesetOk = false;
-        setInsertionMode(InsertionMode::Text);
+        m_insertionMode = InsertionMode::Text;
         return;
     }
-    if (token->name() == xmpTag) {
+    if (token.name() == xmpTag) {
         processFakePEndTagIfPInButtonScope();
         m_tree.reconstructTheActiveFormattingElements();
         m_framesetOk = false;
         processGenericRawTextStartTag(token);
         return;
     }
-    if (token->name() == iframeTag) {
+    if (token.name() == iframeTag) {
         m_framesetOk = false;
         processGenericRawTextStartTag(token);
         return;
     }
-    if (token->name() == noembedTag && m_options.pluginsEnabled) {
+    if (token.name() == noembedTag && m_options.pluginsEnabled) {
         processGenericRawTextStartTag(token);
         return;
     }
-    if (token->name() == noscriptTag && m_options.scriptEnabled) {
+    if (token.name() == noscriptTag && m_options.scriptEnabled) {
         processGenericRawTextStartTag(token);
         return;
     }
-    if (token->name() == selectTag) {
+    if (token.name() == selectTag) {
         m_tree.reconstructTheActiveFormattingElements();
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         m_framesetOk = false;
         if (m_insertionMode == InsertionMode::InTable
             || m_insertionMode == InsertionMode::InCaption
@@ -862,85 +842,86 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
             || m_insertionMode == InsertionMode::InTableBody
             || m_insertionMode == InsertionMode::InRow
             || m_insertionMode == InsertionMode::InCell)
-            setInsertionMode(InsertionMode::InSelectInTable);
+            m_insertionMode = InsertionMode::InSelectInTable;
         else
-            setInsertionMode(InsertionMode::InSelect);
+            m_insertionMode = InsertionMode::InSelect;
         return;
     }
-    if (token->name() == optgroupTag || token->name() == optionTag) {
+    if (token.name() == optgroupTag || token.name() == optionTag) {
         if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node())) {
             AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
-            processEndTag(&endOption);
+            processEndTag(endOption);
         }
         m_tree.reconstructTheActiveFormattingElements();
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         return;
     }
-    if (token->name() == rbTag || token->name() == rtcTag) {
+    if (token.name() == rbTag || token.name() == rtcTag) {
         if (m_tree.openElements()->inScope(rubyTag.localName())) {
             m_tree.generateImpliedEndTags();
             if (!m_tree.currentStackItem()->hasTagName(rubyTag))
                 parseError(token);
         }
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         return;
     }
-    if (token->name() == rtTag || token->name() == rpTag) {
+    if (token.name() == rtTag || token.name() == rpTag) {
         if (m_tree.openElements()->inScope(rubyTag.localName())) {
             m_tree.generateImpliedEndTagsWithExclusion(rtcTag.localName());
             if (!m_tree.currentStackItem()->hasTagName(rubyTag) && !m_tree.currentStackItem()->hasTagName(rtcTag))
                 parseError(token);
         }
-        m_tree.insertHTMLElement(token);
+        m_tree.insertHTMLElement(&token);
         return;
     }
-    if (token->name() == MathMLNames::mathTag.localName()) {
+    if (token.name() == MathMLNames::mathTag.localName()) {
         m_tree.reconstructTheActiveFormattingElements();
-        adjustMathMLAttributes(*token);
-        adjustForeignAttributes(*token);
-        m_tree.insertForeignElement(token, MathMLNames::mathmlNamespaceURI);
+        adjustMathMLAttributes(token);
+        adjustForeignAttributes(token);
+        m_tree.insertForeignElement(&token, MathMLNames::mathmlNamespaceURI);
         return;
     }
-    if (token->name() == SVGNames::svgTag.localName()) {
+    if (token.name() == SVGNames::svgTag.localName()) {
         m_tree.reconstructTheActiveFormattingElements();
-        adjustSVGAttributes(*token);
-        adjustForeignAttributes(*token);
-        m_tree.insertForeignElement(token, SVGNames::svgNamespaceURI);
+        adjustSVGAttributes(token);
+        adjustForeignAttributes(token);
+        m_tree.insertForeignElement(&token, SVGNames::svgNamespaceURI);
         return;
     }
-    if (isCaptionColOrColgroupTag(token->name())
-        || token->name() == frameTag
-        || token->name() == headTag
-        || isTableBodyContextTag(token->name())
-        || isTableCellContextTag(token->name())
-        || token->name() == trTag) {
+    if (isCaptionColOrColgroupTag(token.name())
+        || token.name() == frameTag
+        || token.name() == headTag
+        || isTableBodyContextTag(token.name())
+        || isTableCellContextTag(token.name())
+        || token.name() == trTag) {
         parseError(token);
         return;
     }
 #if ENABLE(TEMPLATE_ELEMENT)
-    if (token->name() == templateTag) {
+    if (token.name() == templateTag) {
         processTemplateStartTag(token);
         return;
     }
 #endif
     m_tree.reconstructTheActiveFormattingElements();
-    m_tree.insertHTMLElement(token);
+    m_tree.insertHTMLElement(&token);
 }
 
 #if ENABLE(TEMPLATE_ELEMENT)
-void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken* token)
+
+void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken& token)
 {
     m_tree.activeFormattingElements()->appendMarker();
-    m_tree.insertHTMLElement(token);
+    m_tree.insertHTMLElement(&token);
     m_templateInsertionModes.append(InsertionMode::TemplateContents);
-    setInsertionMode(InsertionMode::TemplateContents);
+    m_insertionMode = InsertionMode::TemplateContents;
 }
 
-bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken* token)
+bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken& token)
 {
-    ASSERT(token->name() == templateTag.localName());
+    ASSERT(token.name() == templateTag.localName());
     if (!m_tree.openElements()->hasTemplateInHTMLScope()) {
-        ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && m_fragmentContext.contextElement()->hasTagName(templateTag)));
+        ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && m_fragmentContext.contextElement().hasTagName(templateTag)));
         parseError(token);
         return false;
     }
@@ -954,15 +935,16 @@ bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken* token)
     return true;
 }
 
-bool HTMLTreeBuilder::processEndOfFileForInTemplateContents(AtomicHTMLToken* token)
+bool HTMLTreeBuilder::processEndOfFileForInTemplateContents(AtomicHTMLToken& token)
 {
     AtomicHTMLToken endTemplate(HTMLToken::EndTag, templateTag.localName());
-    if (!processTemplateEndTag(&endTemplate))
+    if (!processTemplateEndTag(endTemplate))
         return false;
 
     processEndOfFile(token);
     return true;
 }
+
 #endif
 
 bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
@@ -978,14 +960,14 @@ bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
         return false;
     }
     m_tree.openElements()->pop();
-    setInsertionMode(InsertionMode::InTable);
+    m_insertionMode = InsertionMode::InTable;
     return true;
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#close-the-cell
 void HTMLTreeBuilder::closeTheCell()
 {
-    ASSERT(insertionMode() == InsertionMode::InCell);
+    ASSERT(m_insertionMode == InsertionMode::InCell);
     if (m_tree.openElements()->inTableScope(tdTag)) {
         ASSERT(!m_tree.openElements()->inTableScope(thTag));
         processFakeEndTag(tdTag);
@@ -993,45 +975,45 @@ void HTMLTreeBuilder::closeTheCell()
     }
     ASSERT(m_tree.openElements()->inTableScope(thTag));
     processFakeEndTag(thTag);
-    ASSERT(insertionMode() == InsertionMode::InRow);
+    ASSERT(m_insertionMode == InsertionMode::InRow);
 }
 
-void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::StartTag);
-    if (token->name() == captionTag) {
+    ASSERT(token.type() == HTMLToken::StartTag);
+    if (token.name() == captionTag) {
         m_tree.openElements()->popUntilTableScopeMarker();
         m_tree.activeFormattingElements()->appendMarker();
-        m_tree.insertHTMLElement(token);
-        setInsertionMode(InsertionMode::InCaption);
+        m_tree.insertHTMLElement(&token);
+        m_insertionMode = InsertionMode::InCaption;
         return;
     }
-    if (token->name() == colgroupTag) {
+    if (token.name() == colgroupTag) {
         m_tree.openElements()->popUntilTableScopeMarker();
-        m_tree.insertHTMLElement(token);
-        setInsertionMode(InsertionMode::InColumnGroup);
+        m_tree.insertHTMLElement(&token);
+        m_insertionMode = InsertionMode::InColumnGroup;
         return;
     }
-    if (token->name() == colTag) {
+    if (token.name() == colTag) {
         processFakeStartTag(colgroupTag);
-        ASSERT(insertionMode() == InsertionMode::InColumnGroup);
+        ASSERT(m_insertionMode == InsertionMode::InColumnGroup);
         processStartTag(token);
         return;
     }
-    if (isTableBodyContextTag(token->name())) {
+    if (isTableBodyContextTag(token.name())) {
         m_tree.openElements()->popUntilTableScopeMarker();
-        m_tree.insertHTMLElement(token);
-        setInsertionMode(InsertionMode::InTableBody);
+        m_tree.insertHTMLElement(&token);
+        m_insertionMode = InsertionMode::InTableBody;
         return;
     }
-    if (isTableCellContextTag(token->name())
-        || token->name() == trTag) {
+    if (isTableCellContextTag(token.name())
+        || token.name() == trTag) {
         processFakeStartTag(tbodyTag);
-        ASSERT(insertionMode() == InsertionMode::InTableBody);
+        ASSERT(m_insertionMode == InsertionMode::InTableBody);
         processStartTag(token);
         return;
     }
-    if (token->name() == tableTag) {
+    if (token.name() == tableTag) {
         parseError(token);
         if (!processTableEndTagForInTable()) {
             ASSERT(isParsingFragmentOrTemplateContents());
@@ -1040,29 +1022,29 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken* token)
         processStartTag(token);
         return;
     }
-    if (token->name() == styleTag || token->name() == scriptTag) {
+    if (token.name() == styleTag || token.name() == scriptTag) {
         processStartTagForInHead(token);
         return;
     }
-    if (token->name() == inputTag) {
-        Attribute* typeAttribute = token->getAttributeItem(typeAttr);
+    if (token.name() == inputTag) {
+        Attribute* typeAttribute = token.getAttributeItem(typeAttr);
         if (typeAttribute && equalIgnoringCase(typeAttribute->value(), "hidden")) {
             parseError(token);
-            m_tree.insertSelfClosingHTMLElement(token);
+            m_tree.insertSelfClosingHTMLElement(&token);
             return;
         }
         // Fall through to "anything else" case.
     }
-    if (token->name() == formTag) {
+    if (token.name() == formTag) {
         parseError(token);
         if (m_tree.form() && !isParsingTemplateContents())
             return;
-        m_tree.insertHTMLFormElement(token, true);
+        m_tree.insertHTMLFormElement(&token, true);
         m_tree.openElements()->pop();
         return;
     }
 #if ENABLE(TEMPLATE_ELEMENT)
-    if (token->name() == templateTag) {
+    if (token.name() == templateTag) {
         processTemplateStartTag(token);
         return;
     }
@@ -1072,71 +1054,70 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken* token)
     processStartTagForInBody(token);
 }
 
-void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::StartTag);
-    switch (insertionMode()) {
+    ASSERT(token.type() == HTMLToken::StartTag);
+    switch (m_insertionMode) {
     case InsertionMode::Initial:
-        ASSERT(insertionMode() == InsertionMode::Initial);
         defaultForInitial();
+        ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
         FALLTHROUGH;
     case InsertionMode::BeforeHTML:
-        ASSERT(insertionMode() == InsertionMode::BeforeHTML);
-        if (token->name() == htmlTag) {
-            m_tree.insertHTMLHtmlStartTagBeforeHTML(token);
-            setInsertionMode(InsertionMode::BeforeHead);
+        if (token.name() == htmlTag) {
+            m_tree.insertHTMLHtmlStartTagBeforeHTML(&token);
+            m_insertionMode = InsertionMode::BeforeHead;
             return;
         }
         defaultForBeforeHTML();
+        ASSERT(m_insertionMode == InsertionMode::BeforeHead);
         FALLTHROUGH;
     case InsertionMode::BeforeHead:
-        ASSERT(insertionMode() == InsertionMode::BeforeHead);
-        if (token->name() == htmlTag) {
+        if (token.name() == htmlTag) {
             processHtmlStartTagForInBody(token);
             return;
         }
-        if (token->name() == headTag) {
-            m_tree.insertHTMLHeadElement(token);
-            setInsertionMode(InsertionMode::InHead);
+        if (token.name() == headTag) {
+            m_tree.insertHTMLHeadElement(&token);
+            m_insertionMode = InsertionMode::InHead;
             return;
         }
         defaultForBeforeHead();
+        ASSERT(m_insertionMode == InsertionMode::InHead);
         FALLTHROUGH;
     case InsertionMode::InHead:
-        ASSERT(insertionMode() == InsertionMode::InHead);
         if (processStartTagForInHead(token))
             return;
         defaultForInHead();
+        ASSERT(m_insertionMode == InsertionMode::AfterHead);
         FALLTHROUGH;
     case InsertionMode::AfterHead:
-        ASSERT(insertionMode() == InsertionMode::AfterHead);
-        if (token->name() == htmlTag) {
+        if (token.name() == htmlTag) {
             processHtmlStartTagForInBody(token);
             return;
         }
-        if (token->name() == bodyTag) {
+        if (token.name() == bodyTag) {
             m_framesetOk = false;
-            m_tree.insertHTMLBodyElement(token);
-            setInsertionMode(InsertionMode::InBody);
+            m_tree.insertHTMLBodyElement(&token);
+            m_insertionMode = InsertionMode::InBody;
             return;
         }
-        if (token->name() == framesetTag) {
-            m_tree.insertHTMLElement(token);
-            setInsertionMode(InsertionMode::InFrameset);
+        if (token.name() == framesetTag) {
+            m_tree.insertHTMLElement(&token);
+            m_insertionMode = InsertionMode::InFrameset;
             return;
         }
-        if (token->name() == baseTag
-            || token->name() == basefontTag
-            || token->name() == bgsoundTag
-            || token->name() == linkTag
-            || token->name() == metaTag
-            || token->name() == noframesTag
-            || token->name() == scriptTag
-            || token->name() == styleTag
+        if (token.name() == baseTag
+            || token.name() == basefontTag
+            || token.name() == bgsoundTag
+            || token.name() == linkTag
+            || token.name() == metaTag
+            || token.name() == noframesTag
+            || token.name() == scriptTag
+            || token.name() == styleTag
 #if ENABLE(TEMPLATE_ELEMENT)
-            || token->name() == templateTag
+            || token.name() == templateTag
 #endif
-            || token->name() == titleTag) {
+            || token.name() == titleTag) {
             parseError(token);
             ASSERT(m_tree.head());
             m_tree.openElements()->pushHTMLHeadElement(m_tree.headStackItem());
@@ -1144,26 +1125,25 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
             m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
             return;
         }
-        if (token->name() == headTag) {
+        if (token.name() == headTag) {
             parseError(token);
             return;
         }
         defaultForAfterHead();
+        ASSERT(m_insertionMode == InsertionMode::InBody);
         FALLTHROUGH;
     case InsertionMode::InBody:
-        ASSERT(insertionMode() == InsertionMode::InBody);
         processStartTagForInBody(token);
+        ASSERT(m_insertionMode == InsertionMode::InTable);
         break;
     case InsertionMode::InTable:
-        ASSERT(insertionMode() == InsertionMode::InTable);
         processStartTagForInTable(token);
         break;
     case InsertionMode::InCaption:
-        ASSERT(insertionMode() == InsertionMode::InCaption);
-        if (isCaptionColOrColgroupTag(token->name())
-            || isTableBodyContextTag(token->name())
-            || isTableCellContextTag(token->name())
-            || token->name() == trTag) {
+        if (isCaptionColOrColgroupTag(token.name())
+            || isTableBodyContextTag(token.name())
+            || isTableCellContextTag(token.name())
+            || token.name() == trTag) {
             parseError(token);
             if (!processCaptionEndTagForInCaption()) {
                 ASSERT(isParsingFragment());
@@ -1175,17 +1155,16 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
         processStartTagForInBody(token);
         break;
     case InsertionMode::InColumnGroup:
-        ASSERT(insertionMode() == InsertionMode::InColumnGroup);
-        if (token->name() == htmlTag) {
+        if (token.name() == htmlTag) {
             processHtmlStartTagForInBody(token);
             return;
         }
-        if (token->name() == colTag) {
-            m_tree.insertSelfClosingHTMLElement(token);
+        if (token.name() == colTag) {
+            m_tree.insertSelfClosingHTMLElement(&token);
             return;
         }
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+        if (token.name() == templateTag) {
             processTemplateStartTag(token);
             return;
         }
@@ -1197,21 +1176,20 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
         processStartTag(token);
         break;
     case InsertionMode::InTableBody:
-        ASSERT(insertionMode() == InsertionMode::InTableBody);
-        if (token->name() == trTag) {
+        if (token.name() == trTag) {
             m_tree.openElements()->popUntilTableBodyScopeMarker(); // How is there ever anything to pop?
-            m_tree.insertHTMLElement(token);
-            setInsertionMode(InsertionMode::InRow);
+            m_tree.insertHTMLElement(&token);
+            m_insertionMode = InsertionMode::InRow;
             return;
         }
-        if (isTableCellContextTag(token->name())) {
+        if (isTableCellContextTag(token.name())) {
             parseError(token);
             processFakeStartTag(trTag);
-            ASSERT(insertionMode() == InsertionMode::InRow);
+            ASSERT(m_insertionMode == InsertionMode::InRow);
             processStartTag(token);
             return;
         }
-        if (isCaptionColOrColgroupTag(token->name()) || isTableBodyContextTag(token->name())) {
+        if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name())) {
             // FIXME: This is slow.
             if (!m_tree.openElements()->inTableScope(tbodyTag) && !m_tree.openElements()->inTableScope(theadTag) && !m_tree.openElements()->inTableScope(tfootTag)) {
                 ASSERT(isParsingFragmentOrTemplateContents());
@@ -1227,33 +1205,31 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
         processStartTagForInTable(token);
         break;
     case InsertionMode::InRow:
-        ASSERT(insertionMode() == InsertionMode::InRow);
-        if (isTableCellContextTag(token->name())) {
+        if (isTableCellContextTag(token.name())) {
             m_tree.openElements()->popUntilTableRowScopeMarker();
-            m_tree.insertHTMLElement(token);
-            setInsertionMode(InsertionMode::InCell);
+            m_tree.insertHTMLElement(&token);
+            m_insertionMode = InsertionMode::InCell;
             m_tree.activeFormattingElements()->appendMarker();
             return;
         }
-        if (token->name() == trTag
-            || isCaptionColOrColgroupTag(token->name())
-            || isTableBodyContextTag(token->name())) {
+        if (token.name() == trTag
+            || isCaptionColOrColgroupTag(token.name())
+            || isTableBodyContextTag(token.name())) {
             if (!processTrEndTagForInRow()) {
                 ASSERT(isParsingFragmentOrTemplateContents());
                 return;
             }
-            ASSERT(insertionMode() == InsertionMode::InTableBody);
+            ASSERT(m_insertionMode == InsertionMode::InTableBody);
             processStartTag(token);
             return;
         }
         processStartTagForInTable(token);
         break;
     case InsertionMode::InCell:
-        ASSERT(insertionMode() == InsertionMode::InCell);
-        if (isCaptionColOrColgroupTag(token->name())
-            || isTableCellContextTag(token->name())
-            || token->name() == trTag
-            || isTableBodyContextTag(token->name())) {
+        if (isCaptionColOrColgroupTag(token.name())
+            || isTableCellContextTag(token.name())
+            || token.name() == trTag
+            || isTableBodyContextTag(token.name())) {
             // FIXME: This could be more efficient.
             if (!m_tree.openElements()->inTableScope(tdTag) && !m_tree.openElements()->inTableScope(thTag)) {
                 ASSERT(isParsingFragment());
@@ -1268,31 +1244,29 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
         break;
     case InsertionMode::AfterBody:
     case InsertionMode::AfterAfterBody:
-        ASSERT(insertionMode() == InsertionMode::AfterBody || insertionMode() == InsertionMode::AfterAfterBody);
-        if (token->name() == htmlTag) {
+        if (token.name() == htmlTag) {
             processHtmlStartTagForInBody(token);
             return;
         }
-        setInsertionMode(InsertionMode::InBody);
+        m_insertionMode = InsertionMode::InBody;
         processStartTag(token);
         break;
     case InsertionMode::InHeadNoscript:
-        ASSERT(insertionMode() == InsertionMode::InHeadNoscript);
-        if (token->name() == htmlTag) {
+        if (token.name() == htmlTag) {
             processHtmlStartTagForInBody(token);
             return;
         }
-        if (token->name() == basefontTag
-            || token->name() == bgsoundTag
-            || token->name() == linkTag
-            || token->name() == metaTag
-            || token->name() == noframesTag
-            || token->name() == styleTag) {
+        if (token.name() == basefontTag
+            || token.name() == bgsoundTag
+            || token.name() == linkTag
+            || token.name() == metaTag
+            || token.name() == noframesTag
+            || token.name() == styleTag) {
             bool didProcess = processStartTagForInHead(token);
             ASSERT_UNUSED(didProcess, didProcess);
             return;
         }
-        if (token->name() == htmlTag || token->name() == noscriptTag) {
+        if (token.name() == htmlTag || token.name() == noscriptTag) {
             parseError(token);
             return;
         }
@@ -1300,25 +1274,24 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
         processToken(token);
         break;
     case InsertionMode::InFrameset:
-        ASSERT(insertionMode() == InsertionMode::InFrameset);
-        if (token->name() == htmlTag) {
+        if (token.name() == htmlTag) {
             processHtmlStartTagForInBody(token);
             return;
         }
-        if (token->name() == framesetTag) {
-            m_tree.insertHTMLElement(token);
+        if (token.name() == framesetTag) {
+            m_tree.insertHTMLElement(&token);
             return;
         }
-        if (token->name() == frameTag) {
-            m_tree.insertSelfClosingHTMLElement(token);
+        if (token.name() == frameTag) {
+            m_tree.insertSelfClosingHTMLElement(&token);
             return;
         }
-        if (token->name() == noframesTag) {
+        if (token.name() == noframesTag) {
             processStartTagForInHead(token);
             return;
         }
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+        if (token.name() == templateTag) {
             processTemplateStartTag(token);
             return;
         }
@@ -1327,83 +1300,78 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
         break;
     case InsertionMode::AfterFrameset:
     case InsertionMode::AfterAfterFrameset:
-        ASSERT(insertionMode() == InsertionMode::AfterFrameset || insertionMode() == InsertionMode::AfterAfterFrameset);
-        if (token->name() == htmlTag) {
+        if (token.name() == htmlTag) {
             processHtmlStartTagForInBody(token);
             return;
         }
-        if (token->name() == noframesTag) {
+        if (token.name() == noframesTag) {
             processStartTagForInHead(token);
             return;
         }
         parseError(token);
         break;
     case InsertionMode::InSelectInTable:
-        ASSERT(insertionMode() == InsertionMode::InSelectInTable);
-        if (token->name() == captionTag
-            || token->name() == tableTag
-            || isTableBodyContextTag(token->name())
-            || token->name() == trTag
-            || isTableCellContextTag(token->name())) {
+        if (token.name() == captionTag
+            || token.name() == tableTag
+            || isTableBodyContextTag(token.name())
+            || token.name() == trTag
+            || isTableCellContextTag(token.name())) {
             parseError(token);
             AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
-            processEndTag(&endSelect);
+            processEndTag(endSelect);
             processStartTag(token);
             return;
         }
         FALLTHROUGH;
     case InsertionMode::InSelect:
-        ASSERT(insertionMode() == InsertionMode::InSelect || insertionMode() == InsertionMode::InSelectInTable);
-        if (token->name() == htmlTag) {
+        if (token.name() == htmlTag) {
             processHtmlStartTagForInBody(token);
             return;
         }
-        if (token->name() == optionTag) {
+        if (token.name() == optionTag) {
             if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node())) {
                 AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
-                processEndTag(&endOption);
+                processEndTag(endOption);
             }
-            m_tree.insertHTMLElement(token);
+            m_tree.insertHTMLElement(&token);
             return;
         }
-        if (token->name() == optgroupTag) {
+        if (token.name() == optgroupTag) {
             if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node())) {
                 AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
-                processEndTag(&endOption);
+                processEndTag(endOption);
             }
             if (is<HTMLOptGroupElement>(*m_tree.currentStackItem()->node())) {
                 AtomicHTMLToken endOptgroup(HTMLToken::EndTag, optgroupTag.localName());
-                processEndTag(&endOptgroup);
+                processEndTag(endOptgroup);
             }
-            m_tree.insertHTMLElement(token);
+            m_tree.insertHTMLElement(&token);
             return;
         }
-        if (token->name() == selectTag) {
+        if (token.name() == selectTag) {
             parseError(token);
             AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
-            processEndTag(&endSelect);
+            processEndTag(endSelect);
             return;
         }
-        if (token->name() == inputTag
-            || token->name() == keygenTag
-            || token->name() == textareaTag) {
+        if (token.name() == inputTag || token.name() == keygenTag || token.name() == textareaTag) {
             parseError(token);
             if (!m_tree.openElements()->inSelectScope(selectTag)) {
                 ASSERT(isParsingFragment());
                 return;
             }
             AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
-            processEndTag(&endSelect);
+            processEndTag(endSelect);
             processStartTag(token);
             return;
         }
-        if (token->name() == scriptTag) {
+        if (token.name() == scriptTag) {
             bool didProcess = processStartTagForInHead(token);
             ASSERT_UNUSED(didProcess, didProcess);
             return;
         }
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+        if (token.name() == templateTag) {
             processTemplateStartTag(token);
             return;
         }
@@ -1416,31 +1384,31 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
     case InsertionMode::Text:
         ASSERT_NOT_REACHED();
         break;
-    case InsertionMode::TemplateContents:
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+    case InsertionMode::TemplateContents:
+        if (token.name() == templateTag) {
             processTemplateStartTag(token);
             return;
         }
 
-        if (token->name() == linkTag
-            || token->name() == scriptTag
-            || token->name() == styleTag
-            || token->name() == metaTag) {
+        if (token.name() == linkTag
+            || token.name() == scriptTag
+            || token.name() == styleTag
+            || token.name() == metaTag) {
             processStartTagForInHead(token);
             return;
         }
 
         InsertionMode insertionMode = InsertionMode::TemplateContents;
-        if (token->name() == frameTag)
+        if (token.name() == frameTag)
             insertionMode = InsertionMode::InFrameset;
-        else if (token->name() == colTag)
+        else if (token.name() == colTag)
             insertionMode = InsertionMode::InColumnGroup;
-        else if (isCaptionColOrColgroupTag(token->name()) || isTableBodyContextTag(token->name()))
+        else if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name()))
             insertionMode = InsertionMode::InTable;
-        else if (token->name() == trTag)
+        else if (token.name() == trTag)
             insertionMode = InsertionMode::InTableBody;
-        else if (isTableCellContextTag(token->name()))
+        else if (isTableCellContextTag(token.name()))
             insertionMode = InsertionMode::InRow;
         else
             insertionMode = InsertionMode::InBody;
@@ -1448,17 +1416,15 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
         ASSERT(insertionMode != InsertionMode::TemplateContents);
         ASSERT(m_templateInsertionModes.last() == InsertionMode::TemplateContents);
         m_templateInsertionModes.last() = insertionMode;
-        setInsertionMode(insertionMode);
+        m_insertionMode = insertionMode;
 
         processStartTag(token);
-#else
-        ASSERT_NOT_REACHED();
-#endif
         break;
+#endif
     }
 }
 
-void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken& token)
 {
     parseError(token);
 #if ENABLE(TEMPLATE_ELEMENT)
@@ -1467,45 +1433,43 @@ void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken* token)
         return;
     }
 #endif
-    m_tree.insertHTMLHtmlStartTagInBody(token);
+    m_tree.insertHTMLHtmlStartTagInBody(&token);
 }
 
-bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken* token)
+bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndTag);
-    ASSERT(token->name() == bodyTag);
+    ASSERT(token.type() == HTMLToken::EndTag);
+    ASSERT(token.name() == bodyTag);
     if (!m_tree.openElements()->inScope(bodyTag.localName())) {
         parseError(token);
         return false;
     }
     notImplemented(); // Emit a more specific parse error based on stack contents.
-    setInsertionMode(InsertionMode::AfterBody);
+    m_insertionMode = InsertionMode::AfterBody;
     return true;
 }
 
-void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndTag);
-    HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
-    while (1) {
-        RefPtr<HTMLStackItem> item = record->stackItem();
-        if (item->matchesHTMLTag(token->name())) {
-            m_tree.generateImpliedEndTagsWithExclusion(token->name());
-            if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
+    ASSERT(token.type() == HTMLToken::EndTag);
+    for (auto* record = m_tree.openElements()->topRecord(); ; record = record->next()) {
+        HTMLStackItem& item = *record->stackItem();
+        if (item.matchesHTMLTag(token.name())) {
+            m_tree.generateImpliedEndTagsWithExclusion(token.name());
+            if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
                 parseError(token);
-            m_tree.openElements()->popUntilPopped(item->element());
+            m_tree.openElements()->popUntilPopped(item.element());
             return;
         }
-        if (item->isSpecialNode()) {
+        if (item.isSpecialNode()) {
             parseError(token);
             return;
         }
-        record = record->next();
     }
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody
-void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
+void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
 {
     // The adoption agency algorithm is N^2. We limit the number of iterations
     // to stop from hanging the whole browser. This limit is specified in the
@@ -1517,7 +1481,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
     // 1, 2, 3 and 16 are covered by the for() loop.
     for (int i = 0; i < outerIterationLimit; ++i) {
         // 4.
-        Element* formattingElement = m_tree.activeFormattingElements()->closestElementInScopeWithName(token->name());
+        Element* formattingElement = m_tree.activeFormattingElements()->closestElementInScopeWithName(token.name());
         // 4.a
         if (!formattingElement)
             return processAnyOtherEndTagForInBody(token);
@@ -1528,7 +1492,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
             return;
         }
         // 4.b
-        HTMLElementStack::ElementRecord* formattingElementRecord = m_tree.openElements()->find(formattingElement);
+        auto* formattingElementRecord = m_tree.openElements()->find(formattingElement);
         if (!formattingElementRecord) {
             parseError(token);
             m_tree.activeFormattingElements()->remove(formattingElement);
@@ -1538,7 +1502,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
         if (formattingElement != m_tree.currentElement())
             parseError(token);
         // 5.
-        HTMLElementStack::ElementRecord* furthestBlock = m_tree.openElements()->furthestBlockForFormattingElement(formattingElement);
+        auto* furthestBlock = m_tree.openElements()->furthestBlockForFormattingElement(formattingElement);
         // 6.
         if (!furthestBlock) {
             m_tree.openElements()->popUntilPopped(formattingElement);
@@ -1551,9 +1515,9 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
         // 8.
         HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements()->bookmarkFor(formattingElement);
         // 9.
-        HTMLElementStack::ElementRecord* node = furthestBlock;
-        HTMLElementStack::ElementRecord* nextNode = node->next();
-        HTMLElementStack::ElementRecord* lastNode = furthestBlock;
+        auto* node = furthestBlock;
+        auto* nextNode = node->next();
+        auto* lastNode = furthestBlock;
         // 9.1, 9.2, 9.3 and 9.11 are covered by the for() loop.
         for (int i = 0; i < innerIterationLimit; ++i) {
             // 9.4
@@ -1604,9 +1568,8 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
 {
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#reset-the-insertion-mode-appropriately
     bool last = false;
-    HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
-    while (1) {
-        RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
+    for (auto* record = m_tree.openElements()->topRecord(); ; record = record->next()) {
+        HTMLStackItem* item = record->stackItem().get();
         if (item->node() == m_tree.openElements()->rootNode()) {
             last = true;
 #if ENABLE(TEMPLATE_ELEMENT)
@@ -1616,78 +1579,104 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
             bool shouldCreateItem = true;
 #endif
             if (shouldCreateItem)
-                item = m_fragmentContext.contextElementStackItem();
+                item = &m_fragmentContext.contextElementStackItem();
         }
+
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (item->hasTagName(templateTag))
-            return setInsertionMode(m_templateInsertionModes.last());
+        if (item->hasTagName(templateTag)) {
+            m_insertionMode = m_templateInsertionModes.last();
+            return;
+        }
 #endif
         if (item->hasTagName(selectTag)) {
 #if ENABLE(TEMPLATE_ELEMENT)
             if (!last) {
                 while (item->node() != m_tree.openElements()->rootNode() && !item->hasTagName(templateTag)) {
-                    nodeRecord = nodeRecord->next();
-                    item = nodeRecord->stackItem();
-                    if (is<HTMLTableElement>(*item->node()))
-                        return setInsertionMode(InsertionMode::InSelectInTable);
+                    record = record->next();
+                    item = record->stackItem().get();
+                    if (is<HTMLTableElement>(*item->node())) {
+                        m_insertionMode = InsertionMode::InSelectInTable;
+                        return;
+                    }
                 }
             }
 #endif
-            return setInsertionMode(InsertionMode::InSelect);
-        }
-        if (item->hasTagName(tdTag) || item->hasTagName(thTag))
-            return setInsertionMode(InsertionMode::InCell);
-        if (item->hasTagName(trTag))
-            return setInsertionMode(InsertionMode::InRow);
-        if (item->hasTagName(tbodyTag) || item->hasTagName(theadTag) || item->hasTagName(tfootTag))
-            return setInsertionMode(InsertionMode::InTableBody);
-        if (item->hasTagName(captionTag))
-            return setInsertionMode(InsertionMode::InCaption);
+            m_insertionMode = InsertionMode::InSelect;
+            return;
+        }
+        if (item->hasTagName(tdTag) || item->hasTagName(thTag)) {
+            m_insertionMode = InsertionMode::InCell;
+            return;
+        }
+        if (item->hasTagName(trTag)) {
+            m_insertionMode = InsertionMode::InRow;
+            return;
+        }
+        if (item->hasTagName(tbodyTag) || item->hasTagName(theadTag) || item->hasTagName(tfootTag)) {
+            m_insertionMode = InsertionMode::InTableBody;
+            return;
+        }
+        if (item->hasTagName(captionTag)) {
+            m_insertionMode = InsertionMode::InCaption;
+            return;
+        }
         if (item->hasTagName(colgroupTag)) {
-            return setInsertionMode(InsertionMode::InColumnGroup);
+            m_insertionMode = InsertionMode::InColumnGroup;
+            return;
+        }
+        if (is<HTMLTableElement>(*item->node())) {
+            m_insertionMode = InsertionMode::InTable;
+            return;
         }
-        if (is<HTMLTableElement>(*item->node()))
-            return setInsertionMode(InsertionMode::InTable);
         if (item->hasTagName(headTag)) {
 #if ENABLE(TEMPLATE_ELEMENT)
-            if (!m_fragmentContext.fragment() || m_fragmentContext.contextElement() != item->node())
-                return setInsertionMode(InsertionMode::InHead);
+            if (!m_fragmentContext.fragment() || &m_fragmentContext.contextElement() != item->node()) {
+                m_insertionMode = InsertionMode::InHead;
+                return;
+            }
 #endif
-            return setInsertionMode(InsertionMode::InBody);
+            m_insertionMode = InsertionMode::InBody;
+            return;
+        }
+        if (item->hasTagName(bodyTag)) {
+            m_insertionMode = InsertionMode::InBody;
+            return;
         }
-        if (item->hasTagName(bodyTag))
-            return setInsertionMode(InsertionMode::InBody);
         if (item->hasTagName(framesetTag)) {
-            return setInsertionMode(InsertionMode::InFrameset);
+            m_insertionMode = InsertionMode::InFrameset;
+            return;
         }
         if (item->hasTagName(htmlTag)) {
-            if (m_tree.headStackItem())
-                return setInsertionMode(InsertionMode::AfterHead);
+            if (m_tree.headStackItem()) {
+                m_insertionMode = InsertionMode::AfterHead;
+                return;
+            }
             ASSERT(isParsingFragment());
-            return setInsertionMode(InsertionMode::BeforeHead);
+            m_insertionMode = InsertionMode::BeforeHead;
+            return;
         }
         if (last) {
             ASSERT(isParsingFragment());
-            return setInsertionMode(InsertionMode::InBody);
+            m_insertionMode = InsertionMode::InBody;
+            return;
         }
-        nodeRecord = nodeRecord->next();
     }
 }
 
-void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndTag);
-    if (isTableBodyContextTag(token->name())) {
-        if (!m_tree.openElements()->inTableScope(token->name())) {
+    ASSERT(token.type() == HTMLToken::EndTag);
+    if (isTableBodyContextTag(token.name())) {
+        if (!m_tree.openElements()->inTableScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.openElements()->popUntilTableBodyScopeMarker();
         m_tree.openElements()->pop();
-        setInsertionMode(InsertionMode::InTable);
+        m_insertionMode = InsertionMode::InTable;
         return;
     }
-    if (token->name() == tableTag) {
+    if (token.name() == tableTag) {
         // FIXME: This is slow.
         if (!m_tree.openElements()->inTableScope(tbodyTag) && !m_tree.openElements()->inTableScope(theadTag) && !m_tree.openElements()->inTableScope(tfootTag)) {
             ASSERT(isParsingFragmentOrTemplateContents());
@@ -1700,83 +1689,83 @@ void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken* token)
         processEndTag(token);
         return;
     }
-    if (token->name() == bodyTag
-        || isCaptionColOrColgroupTag(token->name())
-        || token->name() == htmlTag
-        || isTableCellContextTag(token->name())
-        || token->name() == trTag) {
+    if (token.name() == bodyTag
+        || isCaptionColOrColgroupTag(token.name())
+        || token.name() == htmlTag
+        || isTableCellContextTag(token.name())
+        || token.name() == trTag) {
         parseError(token);
         return;
     }
     processEndTagForInTable(token);
 }
 
-void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndTag);
-    if (token->name() == trTag) {
+    ASSERT(token.type() == HTMLToken::EndTag);
+    if (token.name() == trTag) {
         processTrEndTagForInRow();
         return;
     }
-    if (token->name() == tableTag) {
+    if (token.name() == tableTag) {
         if (!processTrEndTagForInRow()) {
             ASSERT(isParsingFragmentOrTemplateContents());
             return;
         }
-        ASSERT(insertionMode() == InsertionMode::InTableBody);
+        ASSERT(m_insertionMode == InsertionMode::InTableBody);
         processEndTag(token);
         return;
     }
-    if (isTableBodyContextTag(token->name())) {
-        if (!m_tree.openElements()->inTableScope(token->name())) {
+    if (isTableBodyContextTag(token.name())) {
+        if (!m_tree.openElements()->inTableScope(token.name())) {
             parseError(token);
             return;
         }
         processFakeEndTag(trTag);
-        ASSERT(insertionMode() == InsertionMode::InTableBody);
+        ASSERT(m_insertionMode == InsertionMode::InTableBody);
         processEndTag(token);
         return;
     }
-    if (token->name() == bodyTag
-        || isCaptionColOrColgroupTag(token->name())
-        || token->name() == htmlTag
-        || isTableCellContextTag(token->name())) {
+    if (token.name() == bodyTag
+        || isCaptionColOrColgroupTag(token.name())
+        || token.name() == htmlTag
+        || isTableCellContextTag(token.name())) {
         parseError(token);
         return;
     }
     processEndTagForInTable(token);
 }
 
-void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndTag);
-    if (isTableCellContextTag(token->name())) {
-        if (!m_tree.openElements()->inTableScope(token->name())) {
+    ASSERT(token.type() == HTMLToken::EndTag);
+    if (isTableCellContextTag(token.name())) {
+        if (!m_tree.openElements()->inTableScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTags();
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
+        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token->name());
+        m_tree.openElements()->popUntilPopped(token.name());
         m_tree.activeFormattingElements()->clearToLastMarker();
-        setInsertionMode(InsertionMode::InRow);
+        m_insertionMode = InsertionMode::InRow;
         return;
     }
-    if (token->name() == bodyTag
-        || isCaptionColOrColgroupTag(token->name())
-        || token->name() == htmlTag) {
+    if (token.name() == bodyTag
+        || isCaptionColOrColgroupTag(token.name())
+        || token.name() == htmlTag) {
         parseError(token);
         return;
     }
-    if (token->name() == tableTag
-        || token->name() == trTag
-        || isTableBodyContextTag(token->name())) {
-        if (!m_tree.openElements()->inTableScope(token->name())) {
+    if (token.name() == tableTag
+        || token.name() == trTag
+        || isTableBodyContextTag(token.name())) {
+        if (!m_tree.openElements()->inTableScope(token.name())) {
 #if ENABLE(TEMPLATE_ELEMENT)
-            ASSERT(isTableBodyContextTag(token->name()) || m_tree.openElements()->inTableScope(templateTag) || isParsingFragment());
+            ASSERT(isTableBodyContextTag(token.name()) || m_tree.openElements()->inTableScope(templateTag) || isParsingFragment());
 #else
-            ASSERT(isTableBodyContextTag(token->name()) || isParsingFragment());
+            ASSERT(isTableBodyContextTag(token.name()) || isParsingFragment());
 #endif
             parseError(token);
             return;
@@ -1788,55 +1777,55 @@ void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken* token)
     processEndTagForInBody(token);
 }
 
-void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndTag);
-    if (token->name() == bodyTag) {
+    ASSERT(token.type() == HTMLToken::EndTag);
+    if (token.name() == bodyTag) {
         processBodyEndTagForInBody(token);
         return;
     }
-    if (token->name() == htmlTag) {
+    if (token.name() == htmlTag) {
         AtomicHTMLToken endBody(HTMLToken::EndTag, bodyTag.localName());
-        if (processBodyEndTagForInBody(&endBody))
+        if (processBodyEndTagForInBody(endBody))
             processEndTag(token);
         return;
     }
-    if (token->name() == addressTag
-        || token->name() == articleTag
-        || token->name() == asideTag
-        || token->name() == blockquoteTag
-        || token->name() == buttonTag
-        || token->name() == centerTag
-        || token->name() == detailsTag
-        || token->name() == dirTag
-        || token->name() == divTag
-        || token->name() == dlTag
-        || token->name() == fieldsetTag
-        || token->name() == figcaptionTag
-        || token->name() == figureTag
-        || token->name() == footerTag
-        || token->name() == headerTag
-        || token->name() == hgroupTag
-        || token->name() == listingTag
-        || token->name() == mainTag
-        || token->name() == menuTag
-        || token->name() == navTag
-        || token->name() == olTag
-        || token->name() == preTag
-        || token->name() == sectionTag
-        || token->name() == summaryTag
-        || token->name() == ulTag) {
-        if (!m_tree.openElements()->inScope(token->name())) {
+    if (token.name() == addressTag
+        || token.name() == articleTag
+        || token.name() == asideTag
+        || token.name() == blockquoteTag
+        || token.name() == buttonTag
+        || token.name() == centerTag
+        || token.name() == detailsTag
+        || token.name() == dirTag
+        || token.name() == divTag
+        || token.name() == dlTag
+        || token.name() == fieldsetTag
+        || token.name() == figcaptionTag
+        || token.name() == figureTag
+        || token.name() == footerTag
+        || token.name() == headerTag
+        || token.name() == hgroupTag
+        || token.name() == listingTag
+        || token.name() == mainTag
+        || token.name() == menuTag
+        || token.name() == navTag
+        || token.name() == olTag
+        || token.name() == preTag
+        || token.name() == sectionTag
+        || token.name() == summaryTag
+        || token.name() == ulTag) {
+        if (!m_tree.openElements()->inScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTags();
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
+        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token->name());
+        m_tree.openElements()->popUntilPopped(token.name());
         return;
     }
-    if (token->name() == formTag) {
+    if (token.name() == formTag) {
         if (!isParsingTemplateContents()) {
             RefPtr<Element> node = m_tree.takeForm();
             if (!node || !m_tree.openElements()->inScope(node.get())) {
@@ -1848,89 +1837,86 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken* token)
                 parseError(token);
             m_tree.openElements()->remove(node.get());
         } else {
-            if (!m_tree.openElements()->inScope(token->name())) {
+            if (!m_tree.openElements()->inScope(token.name())) {
                 parseError(token);
                 return;
             }
             m_tree.generateImpliedEndTags();
             if (!m_tree.currentNode()->hasTagName(formTag))
                 parseError(token);
-            m_tree.openElements()->popUntilPopped(token->name());
+            m_tree.openElements()->popUntilPopped(token.name());
         }
     }
-    if (token->name() == pTag) {
-        if (!m_tree.openElements()->inButtonScope(token->name())) {
+    if (token.name() == pTag) {
+        if (!m_tree.openElements()->inButtonScope(token.name())) {
             parseError(token);
             processFakeStartTag(pTag);
-            ASSERT(m_tree.openElements()->inScope(token->name()));
+            ASSERT(m_tree.openElements()->inScope(token.name()));
             processEndTag(token);
             return;
         }
-        m_tree.generateImpliedEndTagsWithExclusion(token->name());
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
+        m_tree.generateImpliedEndTagsWithExclusion(token.name());
+        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token->name());
+        m_tree.openElements()->popUntilPopped(token.name());
         return;
     }
-    if (token->name() == liTag) {
-        if (!m_tree.openElements()->inListItemScope(token->name())) {
+    if (token.name() == liTag) {
+        if (!m_tree.openElements()->inListItemScope(token.name())) {
             parseError(token);
             return;
         }
-        m_tree.generateImpliedEndTagsWithExclusion(token->name());
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
+        m_tree.generateImpliedEndTagsWithExclusion(token.name());
+        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token->name());
+        m_tree.openElements()->popUntilPopped(token.name());
         return;
     }
-    if (token->name() == ddTag
-        || token->name() == dtTag) {
-        if (!m_tree.openElements()->inScope(token->name())) {
+    if (token.name() == ddTag || token.name() == dtTag) {
+        if (!m_tree.openElements()->inScope(token.name())) {
             parseError(token);
             return;
         }
-        m_tree.generateImpliedEndTagsWithExclusion(token->name());
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
+        m_tree.generateImpliedEndTagsWithExclusion(token.name());
+        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token->name());
+        m_tree.openElements()->popUntilPopped(token.name());
         return;
     }
-    if (isNumberedHeaderTag(token->name())) {
+    if (isNumberedHeaderTag(token.name())) {
         if (!m_tree.openElements()->hasNumberedHeaderElementInScope()) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTags();
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
+        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
             parseError(token);
         m_tree.openElements()->popUntilNumberedHeaderElementPopped();
         return;
     }
-    if (isFormattingTag(token->name())) {
+    if (isFormattingTag(token.name())) {
         callTheAdoptionAgency(token);
         return;
     }
-    if (token->name() == appletTag
-        || token->name() == marqueeTag
-        || token->name() == objectTag) {
-        if (!m_tree.openElements()->inScope(token->name())) {
+    if (token.name() == appletTag || token.name() == marqueeTag || token.name() == objectTag) {
+        if (!m_tree.openElements()->inScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTags();
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
+        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token->name());
+        m_tree.openElements()->popUntilPopped(token.name());
         m_tree.activeFormattingElements()->clearToLastMarker();
         return;
     }
-    if (token->name() == brTag) {
+    if (token.name() == brTag) {
         parseError(token);
         processFakeStartTag(brTag);
         return;
     }
 #if ENABLE(TEMPLATE_ELEMENT)
-    if (token->name() == templateTag) {
+    if (token.name() == templateTag) {
         processTemplateEndTag(token);
         return;
     }
@@ -1949,7 +1935,7 @@ bool HTMLTreeBuilder::processCaptionEndTagForInCaption()
     // FIXME: parse error if (!m_tree.currentStackItem()->hasTagName(captionTag))
     m_tree.openElements()->popUntilPopped(captionTag.localName());
     m_tree.activeFormattingElements()->clearToLastMarker();
-    setInsertionMode(InsertionMode::InTable);
+    m_insertionMode = InsertionMode::InTable;
     return true;
 }
 
@@ -1963,7 +1949,7 @@ bool HTMLTreeBuilder::processTrEndTagForInRow()
     m_tree.openElements()->popUntilTableRowScopeMarker();
     ASSERT(m_tree.currentStackItem()->hasTagName(trTag));
     m_tree.openElements()->pop();
-    setInsertionMode(InsertionMode::InTableBody);
+    m_insertionMode = InsertionMode::InTableBody;
     return true;
 }
 
@@ -1979,19 +1965,19 @@ bool HTMLTreeBuilder::processTableEndTagForInTable()
     return true;
 }
 
-void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndTag);
-    if (token->name() == tableTag) {
+    ASSERT(token.type() == HTMLToken::EndTag);
+    if (token.name() == tableTag) {
         processTableEndTagForInTable();
         return;
     }
-    if (token->name() == bodyTag
-        || isCaptionColOrColgroupTag(token->name())
-        || token->name() == htmlTag
-        || isTableBodyContextTag(token->name())
-        || isTableCellContextTag(token->name())
-        || token->name() == trTag) {
+    if (token.name() == bodyTag
+        || isCaptionColOrColgroupTag(token.name())
+        || token.name() == htmlTag
+        || isTableBodyContextTag(token.name())
+        || isTableCellContextTag(token.name())
+        || token.name() == trTag) {
         parseError(token);
         return;
     }
@@ -2001,75 +1987,75 @@ void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken* token)
     processEndTagForInBody(token);
 }
 
-void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndTag);
-    switch (insertionMode()) {
+    ASSERT(token.type() == HTMLToken::EndTag);
+    switch (m_insertionMode) {
     case InsertionMode::Initial:
-        ASSERT(insertionMode() == InsertionMode::Initial);
+        ASSERT(m_insertionMode == InsertionMode::Initial);
         defaultForInitial();
         FALLTHROUGH;
     case InsertionMode::BeforeHTML:
-        ASSERT(insertionMode() == InsertionMode::BeforeHTML);
-        if (token->name() != headTag && token->name() != bodyTag && token->name() != htmlTag && token->name() != brTag) {
+        ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
+        if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
             parseError(token);
             return;
         }
         defaultForBeforeHTML();
         FALLTHROUGH;
     case InsertionMode::BeforeHead:
-        ASSERT(insertionMode() == InsertionMode::BeforeHead);
-        if (token->name() != headTag && token->name() != bodyTag && token->name() != htmlTag && token->name() != brTag) {
+        ASSERT(m_insertionMode == InsertionMode::BeforeHead);
+        if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
             parseError(token);
             return;
         }
         defaultForBeforeHead();
         FALLTHROUGH;
     case InsertionMode::InHead:
-        ASSERT(insertionMode() == InsertionMode::InHead);
+        ASSERT(m_insertionMode == InsertionMode::InHead);
         // FIXME: This case should be broken out into processEndTagForInHead,
         // because other end tag cases now refer to it ("process the token for using the rules of the "in head" insertion mode").
         // but because the logic falls through to InsertionMode::AfterHead, that gets a little messy.
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+        if (token.name() == templateTag) {
             processTemplateEndTag(token);
             return;
         }
 #endif
-        if (token->name() == headTag) {
+        if (token.name() == headTag) {
             m_tree.openElements()->popHTMLHeadElement();
-            setInsertionMode(InsertionMode::AfterHead);
+            m_insertionMode = InsertionMode::AfterHead;
             return;
         }
-        if (token->name() != bodyTag && token->name() != htmlTag && token->name() != brTag) {
+        if (token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
             parseError(token);
             return;
         }
         defaultForInHead();
         FALLTHROUGH;
     case InsertionMode::AfterHead:
-        ASSERT(insertionMode() == InsertionMode::AfterHead);
-        if (token->name() != bodyTag && token->name() != htmlTag && token->name() != brTag) {
+        ASSERT(m_insertionMode == InsertionMode::AfterHead);
+        if (token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
             parseError(token);
             return;
         }
         defaultForAfterHead();
         FALLTHROUGH;
     case InsertionMode::InBody:
-        ASSERT(insertionMode() == InsertionMode::InBody);
+        ASSERT(m_insertionMode == InsertionMode::InBody);
         processEndTagForInBody(token);
         break;
     case InsertionMode::InTable:
-        ASSERT(insertionMode() == InsertionMode::InTable);
+        ASSERT(m_insertionMode == InsertionMode::InTable);
         processEndTagForInTable(token);
         break;
     case InsertionMode::InCaption:
-        ASSERT(insertionMode() == InsertionMode::InCaption);
-        if (token->name() == captionTag) {
+        ASSERT(m_insertionMode == InsertionMode::InCaption);
+        if (token.name() == captionTag) {
             processCaptionEndTagForInCaption();
             return;
         }
-        if (token->name() == tableTag) {
+        if (token.name() == tableTag) {
             parseError(token);
             if (!processCaptionEndTagForInCaption()) {
                 ASSERT(isParsingFragment());
@@ -2078,30 +2064,30 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
             processEndTag(token);
             return;
         }
-        if (token->name() == bodyTag
-            || token->name() == colTag
-            || token->name() == colgroupTag
-            || token->name() == htmlTag
-            || isTableBodyContextTag(token->name())
-            || isTableCellContextTag(token->name())
-            || token->name() == trTag) {
+        if (token.name() == bodyTag
+            || token.name() == colTag
+            || token.name() == colgroupTag
+            || token.name() == htmlTag
+            || isTableBodyContextTag(token.name())
+            || isTableCellContextTag(token.name())
+            || token.name() == trTag) {
             parseError(token);
             return;
         }
         processEndTagForInBody(token);
         break;
     case InsertionMode::InColumnGroup:
-        ASSERT(insertionMode() == InsertionMode::InColumnGroup);
-        if (token->name() == colgroupTag) {
+        ASSERT(m_insertionMode == InsertionMode::InColumnGroup);
+        if (token.name() == colgroupTag) {
             processColgroupEndTagForInColumnGroup();
             return;
         }
-        if (token->name() == colTag) {
+        if (token.name() == colTag) {
             parseError(token);
             return;
         }
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+        if (token.name() == templateTag) {
             processTemplateEndTag(token);
             return;
         }
@@ -2113,44 +2099,44 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
         processEndTag(token);
         break;
     case InsertionMode::InRow:
-        ASSERT(insertionMode() == InsertionMode::InRow);
+        ASSERT(m_insertionMode == InsertionMode::InRow);
         processEndTagForInRow(token);
         break;
     case InsertionMode::InCell:
-        ASSERT(insertionMode() == InsertionMode::InCell);
+        ASSERT(m_insertionMode == InsertionMode::InCell);
         processEndTagForInCell(token);
         break;
     case InsertionMode::InTableBody:
-        ASSERT(insertionMode() == InsertionMode::InTableBody);
+        ASSERT(m_insertionMode == InsertionMode::InTableBody);
         processEndTagForInTableBody(token);
         break;
     case InsertionMode::AfterBody:
-        ASSERT(insertionMode() == InsertionMode::AfterBody);
-        if (token->name() == htmlTag) {
+        ASSERT(m_insertionMode == InsertionMode::AfterBody);
+        if (token.name() == htmlTag) {
             if (isParsingFragment()) {
                 parseError(token);
                 return;
             }
-            setInsertionMode(InsertionMode::AfterAfterBody);
+            m_insertionMode = InsertionMode::AfterAfterBody;
             return;
         }
         FALLTHROUGH;
     case InsertionMode::AfterAfterBody:
-        ASSERT(insertionMode() == InsertionMode::AfterBody || insertionMode() == InsertionMode::AfterAfterBody);
+        ASSERT(m_insertionMode == InsertionMode::AfterBody || m_insertionMode == InsertionMode::AfterAfterBody);
         parseError(token);
-        setInsertionMode(InsertionMode::InBody);
+        m_insertionMode = InsertionMode::InBody;
         processEndTag(token);
         break;
     case InsertionMode::InHeadNoscript:
-        ASSERT(insertionMode() == InsertionMode::InHeadNoscript);
-        if (token->name() == noscriptTag) {
+        ASSERT(m_insertionMode == InsertionMode::InHeadNoscript);
+        if (token.name() == noscriptTag) {
             ASSERT(m_tree.currentStackItem()->hasTagName(noscriptTag));
             m_tree.openElements()->pop();
             ASSERT(m_tree.currentStackItem()->hasTagName(headTag));
-            setInsertionMode(InsertionMode::InHead);
+            m_insertionMode = InsertionMode::InHead;
             return;
         }
-        if (token->name() != brTag) {
+        if (token.name() != brTag) {
             parseError(token);
             return;
         }
@@ -2158,13 +2144,13 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
         processToken(token);
         break;
     case InsertionMode::Text:
-        if (token->name() == scriptTag) {
+        if (token.name() == scriptTag) {
             // Pause ourselves so that parsing stops until the script can be processed by the caller.
             ASSERT(m_tree.currentStackItem()->hasTagName(scriptTag));
             if (scriptingContentIsAllowed(m_tree.parserContentPolicy()))
                 m_scriptToProcess = m_tree.currentElement();
             m_tree.openElements()->pop();
-            setInsertionMode(m_originalInsertionMode);
+            m_insertionMode = m_originalInsertionMode;
 
             if (m_parser.tokenizer()) {
                 // This token will not have been created by the tokenizer if a
@@ -2177,11 +2163,11 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
             return;
         }
         m_tree.openElements()->pop();
-        setInsertionMode(m_originalInsertionMode);
+        m_insertionMode = m_originalInsertionMode;
         break;
     case InsertionMode::InFrameset:
-        ASSERT(insertionMode() == InsertionMode::InFrameset);
-        if (token->name() == framesetTag) {
+        ASSERT(m_insertionMode == InsertionMode::InFrameset);
+        if (token.name() == framesetTag) {
             bool ignoreFramesetForFragmentParsing  = m_tree.currentIsRootNode();
 #if ENABLE(TEMPLATE_ELEMENT)
             ignoreFramesetForFragmentParsing = ignoreFramesetForFragmentParsing || m_tree.openElements()->hasTemplateInHTMLScope();
@@ -2193,46 +2179,46 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
             }
             m_tree.openElements()->pop();
             if (!isParsingFragment() && !m_tree.currentStackItem()->hasTagName(framesetTag))
-                setInsertionMode(InsertionMode::AfterFrameset);
+                m_insertionMode = InsertionMode::AfterFrameset;
             return;
         }
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+        if (token.name() == templateTag) {
             processTemplateEndTag(token);
             return;
         }
 #endif
         break;
     case InsertionMode::AfterFrameset:
-        ASSERT(insertionMode() == InsertionMode::AfterFrameset);
-        if (token->name() == htmlTag) {
-            setInsertionMode(InsertionMode::AfterAfterFrameset);
+        ASSERT(m_insertionMode == InsertionMode::AfterFrameset);
+        if (token.name() == htmlTag) {
+            m_insertionMode = InsertionMode::AfterAfterFrameset;
             return;
         }
         FALLTHROUGH;
     case InsertionMode::AfterAfterFrameset:
-        ASSERT(insertionMode() == InsertionMode::AfterFrameset || insertionMode() == InsertionMode::AfterAfterFrameset);
+        ASSERT(m_insertionMode == InsertionMode::AfterFrameset || m_insertionMode == InsertionMode::AfterAfterFrameset);
         parseError(token);
         break;
     case InsertionMode::InSelectInTable:
-        ASSERT(insertionMode() == InsertionMode::InSelectInTable);
-        if (token->name() == captionTag
-            || token->name() == tableTag
-            || isTableBodyContextTag(token->name())
-            || token->name() == trTag
-            || isTableCellContextTag(token->name())) {
+        ASSERT(m_insertionMode == InsertionMode::InSelectInTable);
+        if (token.name() == captionTag
+            || token.name() == tableTag
+            || isTableBodyContextTag(token.name())
+            || token.name() == trTag
+            || isTableCellContextTag(token.name())) {
             parseError(token);
-            if (m_tree.openElements()->inTableScope(token->name())) {
+            if (m_tree.openElements()->inTableScope(token.name())) {
                 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
-                processEndTag(&endSelect);
+                processEndTag(endSelect);
                 processEndTag(token);
             }
             return;
         }
         FALLTHROUGH;
     case InsertionMode::InSelect:
-        ASSERT(insertionMode() == InsertionMode::InSelect || insertionMode() == InsertionMode::InSelectInTable);
-        if (token->name() == optgroupTag) {
+        ASSERT(m_insertionMode == InsertionMode::InSelect || m_insertionMode == InsertionMode::InSelectInTable);
+        if (token.name() == optgroupTag) {
             if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node()) && m_tree.oneBelowTop() && is<HTMLOptGroupElement>(*m_tree.oneBelowTop()->node()))
                 processFakeEndTag(optionTag);
             if (is<HTMLOptGroupElement>(*m_tree.currentStackItem()->node())) {
@@ -2242,7 +2228,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
             parseError(token);
             return;
         }
-        if (token->name() == optionTag) {
+        if (token.name() == optionTag) {
             if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node())) {
                 m_tree.openElements()->pop();
                 return;
@@ -2250,8 +2236,8 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
             parseError(token);
             return;
         }
-        if (token->name() == selectTag) {
-            if (!m_tree.openElements()->inSelectScope(token->name())) {
+        if (token.name() == selectTag) {
+            if (!m_tree.openElements()->inSelectScope(token.name())) {
                 ASSERT(isParsingFragment());
                 parseError(token);
                 return;
@@ -2261,7 +2247,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
             return;
         }
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+        if (token.name() == templateTag) {
             processTemplateEndTag(token);
             return;
         }
@@ -2271,31 +2257,29 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
         defaultForInTableText();
         processEndTag(token);
         break;
-    case InsertionMode::TemplateContents:
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (token->name() == templateTag) {
+    case InsertionMode::TemplateContents:
+        if (token.name() == templateTag) {
             processTemplateEndTag(token);
             return;
         }
-#else
-        ASSERT_NOT_REACHED();
-#endif
         break;
+#endif
     }
 }
 
-void HTMLTreeBuilder::processComment(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processComment(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::Comment);
+    ASSERT(token.type() == HTMLToken::Comment);
     if (m_insertionMode == InsertionMode::Initial
         || m_insertionMode == InsertionMode::BeforeHTML
         || m_insertionMode == InsertionMode::AfterAfterBody
         || m_insertionMode == InsertionMode::AfterAfterFrameset) {
-        m_tree.insertCommentOnDocument(token);
+        m_tree.insertCommentOnDocument(&token);
         return;
     }
     if (m_insertionMode == InsertionMode::AfterBody) {
-        m_tree.insertCommentOnHTMLHtmlElement(token);
+        m_tree.insertCommentOnHTMLHtmlElement(&token);
         return;
     }
     if (m_insertionMode == InsertionMode::InTableText) {
@@ -2303,18 +2287,19 @@ void HTMLTreeBuilder::processComment(AtomicHTMLToken* token)
         processComment(token);
         return;
     }
-    m_tree.insertComment(token);
+    m_tree.insertComment(&token);
 }
 
-void HTMLTreeBuilder::processCharacter(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processCharacter(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::Character);
+    ASSERT(token.type() == HTMLToken::Character);
     ExternalCharacterTokenBuffer buffer(token);
     processCharacterBuffer(buffer);
 }
 
-// FIXME: Extract the following iOS-specific code into a separate file.
 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
+
+// FIXME: Extract the following iOS-specific code into a separate file.
 // From the string 4089961010, creates a link of the form <a href="tel:4089961010">4089961010</a> and inserts it.
 void HTMLTreeBuilder::insertPhoneNumberLink(const String& string)
 {
@@ -2325,10 +2310,10 @@ void HTMLTreeBuilder::insertPhoneNumberLink(const String& string)
     AtomicHTMLToken aStartToken(HTMLToken::StartTag, aTagLocalName, attributes);
     AtomicHTMLToken aEndToken(HTMLToken::EndTag, aTagLocalName);
 
-    processStartTag(&aStartToken);
+    processStartTag(aStartToken);
     m_tree.executeQueuedTasks();
     m_tree.insertTextNode(string);
-    processEndTag(&aEndToken);
+    processEndTag(aEndToken);
 }
 
 // Locates the phone numbers in the string and deals with it
@@ -2398,6 +2383,7 @@ static inline bool shouldParseTelephoneNumbersInNode(const ContainerNode& node)
     } while (currentNode);
     return true;
 }
+
 #endif // ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
 
 void HTMLTreeBuilder::processCharacterBuffer(ExternalCharacterTokenBuffer& buffer)
@@ -2421,77 +2407,68 @@ ReprocessBuffer:
             return;
     }
 
-    switch (insertionMode()) {
-    case InsertionMode::Initial: {
-        ASSERT(insertionMode() == InsertionMode::Initial);
+    switch (m_insertionMode) {
+    case InsertionMode::Initial:
         buffer.skipLeadingWhitespace();
         if (buffer.isEmpty())
             return;
         defaultForInitial();
+        ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
         FALLTHROUGH;
-    }
-    case InsertionMode::BeforeHTML: {
-        ASSERT(insertionMode() == InsertionMode::BeforeHTML);
+    case InsertionMode::BeforeHTML:
         buffer.skipLeadingWhitespace();
         if (buffer.isEmpty())
             return;
         defaultForBeforeHTML();
+        ASSERT(m_insertionMode == InsertionMode::BeforeHead);
         FALLTHROUGH;
-    }
-    case InsertionMode::BeforeHead: {
-        ASSERT(insertionMode() == InsertionMode::BeforeHead);
+    case InsertionMode::BeforeHead:
         buffer.skipLeadingWhitespace();
         if (buffer.isEmpty())
             return;
         defaultForBeforeHead();
+        ASSERT(m_insertionMode == InsertionMode::InHead);
         FALLTHROUGH;
-    }
     case InsertionMode::InHead: {
-        ASSERT(insertionMode() == InsertionMode::InHead);
         String leadingWhitespace = buffer.takeLeadingWhitespace();
         if (!leadingWhitespace.isEmpty())
             m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
         if (buffer.isEmpty())
             return;
         defaultForInHead();
+        ASSERT(m_insertionMode == InsertionMode::AfterHead);
         FALLTHROUGH;
     }
     case InsertionMode::AfterHead: {
-        ASSERT(insertionMode() == InsertionMode::AfterHead);
         String leadingWhitespace = buffer.takeLeadingWhitespace();
         if (!leadingWhitespace.isEmpty())
             m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
         if (buffer.isEmpty())
             return;
         defaultForAfterHead();
+        ASSERT(m_insertionMode == InsertionMode::InBody);
         FALLTHROUGH;
     }
     case InsertionMode::InBody:
     case InsertionMode::InCaption:
-    case InsertionMode::TemplateContents:
-    case InsertionMode::InCell: {
+    case InsertionMode::InCell:
 #if ENABLE(TEMPLATE_ELEMENT)
-        ASSERT(insertionMode() == InsertionMode::InBody || insertionMode() == InsertionMode::InCaption || insertionMode() == InsertionMode::InCell || insertionMode() == InsertionMode::TemplateContents);
-#else
-        ASSERT(insertionMode() != InsertionMode::TemplateContents);
-        ASSERT(insertionMode() == InsertionMode::InBody || insertionMode() == InsertionMode::InCaption || insertionMode() == InsertionMode::InCell);
+    case InsertionMode::TemplateContents:
 #endif
         processCharacterBufferForInBody(buffer);
         break;
-    }
     case InsertionMode::InTable:
     case InsertionMode::InTableBody:
-    case InsertionMode::InRow: {
-        ASSERT(insertionMode() == InsertionMode::InTable || insertionMode() == InsertionMode::InTableBody || insertionMode() == InsertionMode::InRow);
+    case InsertionMode::InRow:
         ASSERT(m_pendingTableCharacters.isEmpty());
         if (m_tree.currentStackItem()->isElementNode()
-            && (is<HTMLTableElement>(*m_tree.currentStackItem()->node())
+            && (is<HTMLTableElement>(*m_tree.currentStackItem()->element())
                 || m_tree.currentStackItem()->hasTagName(HTMLNames::tbodyTag)
                 || m_tree.currentStackItem()->hasTagName(HTMLNames::tfootTag)
                 || m_tree.currentStackItem()->hasTagName(HTMLNames::theadTag)
                 || m_tree.currentStackItem()->hasTagName(HTMLNames::trTag))) {
             m_originalInsertionMode = m_insertionMode;
-            setInsertionMode(InsertionMode::InTableText);
+            m_insertionMode = InsertionMode::InTableText;
             // Note that we fall through to the InsertionMode::InTableText case below.
         } else {
             HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
@@ -2499,13 +2476,10 @@ ReprocessBuffer:
             break;
         }
         FALLTHROUGH;
-    }
-    case InsertionMode::InTableText: {
+    case InsertionMode::InTableText:
         buffer.giveRemainingTo(m_pendingTableCharacters);
         break;
-    }
     case InsertionMode::InColumnGroup: {
-        ASSERT(insertionMode() == InsertionMode::InColumnGroup);
         String leadingWhitespace = buffer.takeLeadingWhitespace();
         if (!leadingWhitespace.isEmpty())
             m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
@@ -2521,19 +2495,14 @@ ReprocessBuffer:
         goto ReprocessBuffer;
     }
     case InsertionMode::AfterBody:
-    case InsertionMode::AfterAfterBody: {
-        ASSERT(insertionMode() == InsertionMode::AfterBody || insertionMode() == InsertionMode::AfterAfterBody);
+    case InsertionMode::AfterAfterBody:
         // FIXME: parse error
-        setInsertionMode(InsertionMode::InBody);
+        m_insertionMode = InsertionMode::InBody;
         goto ReprocessBuffer;
-    }
-    case InsertionMode::Text: {
-        ASSERT(insertionMode() == InsertionMode::Text);
+    case InsertionMode::Text:
         m_tree.insertTextNode(buffer.takeRemaining());
         break;
-    }
     case InsertionMode::InHeadNoscript: {
-        ASSERT(insertionMode() == InsertionMode::InHeadNoscript);
         String leadingWhitespace = buffer.takeLeadingWhitespace();
         if (!leadingWhitespace.isEmpty())
             m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
@@ -2544,7 +2513,6 @@ ReprocessBuffer:
     }
     case InsertionMode::InFrameset:
     case InsertionMode::AfterFrameset: {
-        ASSERT(insertionMode() == InsertionMode::InFrameset || insertionMode() == InsertionMode::AfterFrameset || insertionMode() == InsertionMode::AfterAfterFrameset);
         String leadingWhitespace = buffer.takeRemainingWhitespace();
         if (!leadingWhitespace.isEmpty())
             m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
@@ -2553,11 +2521,9 @@ ReprocessBuffer:
         break;
     }
     case InsertionMode::InSelectInTable:
-    case InsertionMode::InSelect: {
-        ASSERT(insertionMode() == InsertionMode::InSelect || insertionMode() == InsertionMode::InSelectInTable);
+    case InsertionMode::InSelect:
         m_tree.insertTextNode(buffer.takeRemaining());
         break;
-    }
     case InsertionMode::AfterAfterFrameset: {
         String leadingWhitespace = buffer.takeRemainingWhitespace();
         if (!leadingWhitespace.isEmpty()) {
@@ -2583,64 +2549,55 @@ void HTMLTreeBuilder::processCharacterBufferForInBody(ExternalCharacterTokenBuff
 #else
     m_tree.insertTextNode(characters);
 #endif
-
     if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
         m_framesetOk = false;
 }
 
-void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::EndOfFile);
-    switch (insertionMode()) {
+    ASSERT(token.type() == HTMLToken::EndOfFile);
+    switch (m_insertionMode) {
     case InsertionMode::Initial:
-        ASSERT(insertionMode() == InsertionMode::Initial);
         defaultForInitial();
+        ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
         FALLTHROUGH;
     case InsertionMode::BeforeHTML:
-        ASSERT(insertionMode() == InsertionMode::BeforeHTML);
         defaultForBeforeHTML();
+        ASSERT(m_insertionMode == InsertionMode::BeforeHead);
         FALLTHROUGH;
     case InsertionMode::BeforeHead:
-        ASSERT(insertionMode() == InsertionMode::BeforeHead);
         defaultForBeforeHead();
+        ASSERT(m_insertionMode == InsertionMode::InHead);
         FALLTHROUGH;
     case InsertionMode::InHead:
-        ASSERT(insertionMode() == InsertionMode::InHead);
         defaultForInHead();
+        ASSERT(m_insertionMode == InsertionMode::AfterHead);
         FALLTHROUGH;
     case InsertionMode::AfterHead:
-        ASSERT(insertionMode() == InsertionMode::AfterHead);
         defaultForAfterHead();
+        ASSERT(m_insertionMode == InsertionMode::InBody);
         FALLTHROUGH;
     case InsertionMode::InBody:
     case InsertionMode::InCell:
     case InsertionMode::InCaption:
     case InsertionMode::InRow:
-#if ENABLE(TEMPLATE_ELEMENT)
-        ASSERT(insertionMode() == InsertionMode::InBody || insertionMode() == InsertionMode::InCell || insertionMode() == InsertionMode::InCaption || insertionMode() == InsertionMode::InRow || insertionMode() == InsertionMode::TemplateContents);
-#else
-        ASSERT(insertionMode() != InsertionMode::TemplateContents);
-        ASSERT(insertionMode() == InsertionMode::InBody || insertionMode() == InsertionMode::InCell || insertionMode() == InsertionMode::InCaption || insertionMode() == InsertionMode::InRow);
-#endif
         notImplemented(); // Emit parse error based on what elements are still open.
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (!m_templateInsertionModes.isEmpty())
+        if (!m_templateInsertionModes.isEmpty()) {
             if (processEndOfFileForInTemplateContents(token))
                 return;
+        }
 #endif
         break;
     case InsertionMode::AfterBody:
     case InsertionMode::AfterAfterBody:
-        ASSERT(insertionMode() == InsertionMode::AfterBody || insertionMode() == InsertionMode::AfterAfterBody);
         break;
     case InsertionMode::InHeadNoscript:
-        ASSERT(insertionMode() == InsertionMode::InHeadNoscript);
         defaultForInHeadNoscript();
         processEndOfFile(token);
         return;
     case InsertionMode::AfterFrameset:
     case InsertionMode::AfterAfterFrameset:
-        ASSERT(insertionMode() == InsertionMode::AfterFrameset || insertionMode() == InsertionMode::AfterAfterFrameset);
         break;
     case InsertionMode::InColumnGroup:
         if (m_tree.currentIsRootNode()) {
@@ -2659,14 +2616,14 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token)
     case InsertionMode::InTableBody:
     case InsertionMode::InSelectInTable:
     case InsertionMode::InSelect:
-        ASSERT(insertionMode() == InsertionMode::InSelect || insertionMode() == InsertionMode::InSelectInTable || insertionMode() == InsertionMode::InTable || insertionMode() == InsertionMode::InFrameset || insertionMode() == InsertionMode::InTableBody || insertionMode() == InsertionMode::InColumnGroup);
+        ASSERT(m_insertionMode == InsertionMode::InSelect || m_insertionMode == InsertionMode::InSelectInTable || m_insertionMode == InsertionMode::InTable || m_insertionMode == InsertionMode::InFrameset || m_insertionMode == InsertionMode::InTableBody || m_insertionMode == InsertionMode::InColumnGroup);
         if (m_tree.currentNode() != m_tree.openElements()->rootNode())
             parseError(token);
-
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (!m_templateInsertionModes.isEmpty())
+        if (!m_templateInsertionModes.isEmpty()) {
             if (processEndOfFileForInTemplateContents(token))
                 return;
+        }
 #endif
         break;
     case InsertionMode::InTableText:
@@ -2679,16 +2636,14 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token)
             notImplemented(); // mark the script element as "already started".
         m_tree.openElements()->pop();
         ASSERT(m_originalInsertionMode != InsertionMode::Text);
-        setInsertionMode(m_originalInsertionMode);
+        m_insertionMode = m_originalInsertionMode;
         processEndOfFile(token);
         return;
-    case InsertionMode::TemplateContents:
 #if ENABLE(TEMPLATE_ELEMENT)
+    case InsertionMode::TemplateContents:
         if (processEndOfFileForInTemplateContents(token))
             return;
         break;
-#else
-        ASSERT_NOT_REACHED();
 #endif
     }
     ASSERT(m_tree.currentNode());
@@ -2700,38 +2655,38 @@ void HTMLTreeBuilder::defaultForInitial()
     notImplemented();
     m_tree.setDefaultCompatibilityMode();
     // FIXME: parse error
-    setInsertionMode(InsertionMode::BeforeHTML);
+    m_insertionMode = InsertionMode::BeforeHTML;
 }
 
 void HTMLTreeBuilder::defaultForBeforeHTML()
 {
     AtomicHTMLToken startHTML(HTMLToken::StartTag, htmlTag.localName());
     m_tree.insertHTMLHtmlStartTagBeforeHTML(&startHTML);
-    setInsertionMode(InsertionMode::BeforeHead);
+    m_insertionMode = InsertionMode::BeforeHead;
 }
 
 void HTMLTreeBuilder::defaultForBeforeHead()
 {
     AtomicHTMLToken startHead(HTMLToken::StartTag, headTag.localName());
-    processStartTag(&startHead);
+    processStartTag(startHead);
 }
 
 void HTMLTreeBuilder::defaultForInHead()
 {
     AtomicHTMLToken endHead(HTMLToken::EndTag, headTag.localName());
-    processEndTag(&endHead);
+    processEndTag(endHead);
 }
 
 void HTMLTreeBuilder::defaultForInHeadNoscript()
 {
     AtomicHTMLToken endNoscript(HTMLToken::EndTag, noscriptTag.localName());
-    processEndTag(&endNoscript);
+    processEndTag(endNoscript);
 }
 
 void HTMLTreeBuilder::defaultForAfterHead()
 {
     AtomicHTMLToken startBody(HTMLToken::StartTag, bodyTag.localName());
-    processStartTag(&startBody);
+    processStartTag(startBody);
     m_framesetOk = true;
 }
 
@@ -2745,90 +2700,90 @@ void HTMLTreeBuilder::defaultForInTableText()
         m_tree.reconstructTheActiveFormattingElements();
         m_tree.insertTextNode(characters, NotAllWhitespace);
         m_framesetOk = false;
-        setInsertionMode(m_originalInsertionMode);
+        m_insertionMode = m_originalInsertionMode;
         return;
     }
     m_tree.insertTextNode(characters);
-    setInsertionMode(m_originalInsertionMode);
+    m_insertionMode = m_originalInsertionMode;
 }
 
-bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken* token)
+bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::StartTag);
-    if (token->name() == htmlTag) {
+    ASSERT(token.type() == HTMLToken::StartTag);
+    if (token.name() == htmlTag) {
         processHtmlStartTagForInBody(token);
         return true;
     }
-    if (token->name() == baseTag
-        || token->name() == basefontTag
-        || token->name() == bgsoundTag
-        || token->name() == commandTag
-        || token->name() == linkTag
-        || token->name() == metaTag) {
-        m_tree.insertSelfClosingHTMLElement(token);
+    if (token.name() == baseTag
+        || token.name() == basefontTag
+        || token.name() == bgsoundTag
+        || token.name() == commandTag
+        || token.name() == linkTag
+        || token.name() == metaTag) {
+        m_tree.insertSelfClosingHTMLElement(&token);
         // Note: The custom processing for the <meta> tag is done in HTMLMetaElement::process().
         return true;
     }
-    if (token->name() == titleTag) {
+    if (token.name() == titleTag) {
         processGenericRCDATAStartTag(token);
         return true;
     }
-    if (token->name() == noscriptTag) {
+    if (token.name() == noscriptTag) {
         if (m_options.scriptEnabled) {
             processGenericRawTextStartTag(token);
             return true;
         }
-        m_tree.insertHTMLElement(token);
-        setInsertionMode(InsertionMode::InHeadNoscript);
+        m_tree.insertHTMLElement(&token);
+        m_insertionMode = InsertionMode::InHeadNoscript;
         return true;
     }
-    if (token->name() == noframesTag || token->name() == styleTag) {
+    if (token.name() == noframesTag || token.name() == styleTag) {
         processGenericRawTextStartTag(token);
         return true;
     }
-    if (token->name() == scriptTag) {
+    if (token.name() == scriptTag) {
         processScriptStartTag(token);
-        if (m_options.usePreHTML5ParserQuirks && token->selfClosing())
+        if (m_options.usePreHTML5ParserQuirks && token.selfClosing())
             processFakeEndTag(scriptTag);
         return true;
     }
 #if ENABLE(TEMPLATE_ELEMENT)
-    if (token->name() == templateTag) {
+    if (token.name() == templateTag) {
         processTemplateStartTag(token);
         return true;
     }
 #endif
-    if (token->name() == headTag) {
+    if (token.name() == headTag) {
         parseError(token);
         return true;
     }
     return false;
 }
 
-void HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::StartTag);
-    m_tree.insertHTMLElement(token);
+    ASSERT(token.type() == HTMLToken::StartTag);
+    m_tree.insertHTMLElement(&token);
     if (m_parser.tokenizer())
         m_parser.tokenizer()->setState(HTMLTokenizer::RCDATAState);
     m_originalInsertionMode = m_insertionMode;
-    setInsertionMode(InsertionMode::Text);
+    m_insertionMode = InsertionMode::Text;
 }
 
-void HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::StartTag);
-    m_tree.insertHTMLElement(token);
+    ASSERT(token.type() == HTMLToken::StartTag);
+    m_tree.insertHTMLElement(&token);
     if (m_parser.tokenizer())
         m_parser.tokenizer()->setState(HTMLTokenizer::RAWTEXTState);
     m_originalInsertionMode = m_insertionMode;
-    setInsertionMode(InsertionMode::Text);
+    m_insertionMode = InsertionMode::Text;
 }
 
-void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken& token)
 {
-    ASSERT(token->type() == HTMLToken::StartTag);
-    m_tree.insertScriptElement(token);
+    ASSERT(token.type() == HTMLToken::StartTag);
+    m_tree.insertScriptElement(&token);
     if (m_parser.tokenizer())
         m_parser.tokenizer()->setState(HTMLTokenizer::ScriptDataState);
     m_originalInsertionMode = m_insertionMode;
@@ -2837,55 +2792,55 @@ void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken* token)
 
     m_scriptToProcessStartPosition = position;
 
-    setInsertionMode(InsertionMode::Text);
+    m_insertionMode = InsertionMode::Text;
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/#adjusted-current-node
-HTMLStackItem* HTMLTreeBuilder::adjustedCurrentStackItem() const
+HTMLStackItem& HTMLTreeBuilder::adjustedCurrentStackItem() const
 {
     ASSERT(!m_tree.isEmpty());
     if (isParsingFragment() && m_tree.openElements()->hasOnlyOneElement())
         return m_fragmentContext.contextElementStackItem();
 
-    return m_tree.currentStackItem();
+    return *m_tree.currentStackItem();
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#tree-construction
-bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token)
+bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken& token)
 {
     if (m_tree.isEmpty())
         return false;
-    HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem();
-    if (adjustedCurrentNode->isInHTMLNamespace())
+    HTMLStackItem& adjustedCurrentNode = adjustedCurrentStackItem();
+    if (adjustedCurrentNode.isInHTMLNamespace())
         return false;
-    if (HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurrentNode)) {
-        if (token->type() == HTMLToken::StartTag
-            && token->name() != MathMLNames::mglyphTag
-            && token->name() != MathMLNames::malignmarkTag)
+    if (HTMLElementStack::isMathMLTextIntegrationPoint(&adjustedCurrentNode)) {
+        if (token.type() == HTMLToken::StartTag
+            && token.name() != MathMLNames::mglyphTag
+            && token.name() != MathMLNames::malignmarkTag)
             return false;
-        if (token->type() == HTMLToken::Character)
+        if (token.type() == HTMLToken::Character)
             return false;
     }
-    if (adjustedCurrentNode->hasTagName(MathMLNames::annotation_xmlTag)
-        && token->type() == HTMLToken::StartTag
-        && token->name() == SVGNames::svgTag)
+    if (adjustedCurrentNode.hasTagName(MathMLNames::annotation_xmlTag)
+        && token.type() == HTMLToken::StartTag
+        && token.name() == SVGNames::svgTag)
         return false;
-    if (HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode)) {
-        if (token->type() == HTMLToken::StartTag)
+    if (HTMLElementStack::isHTMLIntegrationPoint(&adjustedCurrentNode)) {
+        if (token.type() == HTMLToken::StartTag)
             return false;
-        if (token->type() == HTMLToken::Character)
+        if (token.type() == HTMLToken::Character)
             return false;
     }
-    if (token->type() == HTMLToken::EndOfFile)
+    if (token.type() == HTMLToken::EndOfFile)
         return false;
     return true;
 }
 
-void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
+void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken& token)
 {
-    HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem();
+    HTMLStackItem& adjustedCurrentNode = adjustedCurrentStackItem();
     
-    switch (token->type()) {
+    switch (token.type()) {
     case HTMLToken::Uninitialized:
         ASSERT_NOT_REACHED();
         break;
@@ -2893,67 +2848,67 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
         parseError(token);
         break;
     case HTMLToken::StartTag: {
-        if (token->name() == bTag
-            || token->name() == bigTag
-            || token->name() == blockquoteTag
-            || token->name() == bodyTag
-            || token->name() == brTag
-            || token->name() == centerTag
-            || token->name() == codeTag
-            || token->name() == ddTag
-            || token->name() == divTag
-            || token->name() == dlTag
-            || token->name() == dtTag
-            || token->name() == emTag
-            || token->name() == embedTag
-            || isNumberedHeaderTag(token->name())
-            || token->name() == headTag
-            || token->name() == hrTag
-            || token->name() == iTag
-            || token->name() == imgTag
-            || token->name() == liTag
-            || token->name() == listingTag
-            || token->name() == menuTag
-            || token->name() == metaTag
-            || token->name() == nobrTag
-            || token->name() == olTag
-            || token->name() == pTag
-            || token->name() == preTag
-            || token->name() == rubyTag
-            || token->name() == sTag
-            || token->name() == smallTag
-            || token->name() == spanTag
-            || token->name() == strongTag
-            || token->name() == strikeTag
-            || token->name() == subTag
-            || token->name() == supTag
-            || token->name() == tableTag
-            || token->name() == ttTag
-            || token->name() == uTag
-            || token->name() == ulTag
-            || token->name() == varTag
-            || (token->name() == fontTag && (token->getAttributeItem(colorAttr) || token->getAttributeItem(faceAttr) || token->getAttributeItem(sizeAttr)))) {
+        if (token.name() == bTag
+            || token.name() == bigTag
+            || token.name() == blockquoteTag
+            || token.name() == bodyTag
+            || token.name() == brTag
+            || token.name() == centerTag
+            || token.name() == codeTag
+            || token.name() == ddTag
+            || token.name() == divTag
+            || token.name() == dlTag
+            || token.name() == dtTag
+            || token.name() == emTag
+            || token.name() == embedTag
+            || isNumberedHeaderTag(token.name())
+            || token.name() == headTag
+            || token.name() == hrTag
+            || token.name() == iTag
+            || token.name() == imgTag
+            || token.name() == liTag
+            || token.name() == listingTag
+            || token.name() == menuTag
+            || token.name() == metaTag
+            || token.name() == nobrTag
+            || token.name() == olTag
+            || token.name() == pTag
+            || token.name() == preTag
+            || token.name() == rubyTag
+            || token.name() == sTag
+            || token.name() == smallTag
+            || token.name() == spanTag
+            || token.name() == strongTag
+            || token.name() == strikeTag
+            || token.name() == subTag
+            || token.name() == supTag
+            || token.name() == tableTag
+            || token.name() == ttTag
+            || token.name() == uTag
+            || token.name() == ulTag
+            || token.name() == varTag
+            || (token.name() == fontTag && (token.getAttributeItem(colorAttr) || token.getAttributeItem(faceAttr) || token.getAttributeItem(sizeAttr)))) {
             parseError(token);
             m_tree.openElements()->popUntilForeignContentScopeMarker();
             processStartTag(token);
             return;
         }
-        const AtomicString& currentNamespace = adjustedCurrentNode->namespaceURI();
+        const AtomicString& currentNamespace = adjustedCurrentNode.namespaceURI();
         if (currentNamespace == MathMLNames::mathmlNamespaceURI)
-            adjustMathMLAttributes(*token);
+            adjustMathMLAttributes(token);
         if (currentNamespace == SVGNames::svgNamespaceURI) {
-            adjustSVGTagNameCase(*token);
-            adjustSVGAttributes(*token);
+            adjustSVGTagNameCase(token);
+            adjustSVGAttributes(token);
         }
-        adjustForeignAttributes(*token);
-        m_tree.insertForeignElement(token, currentNamespace);
+        adjustForeignAttributes(token);
+        m_tree.insertForeignElement(&token, currentNamespace);
         break;
     }
     case HTMLToken::EndTag: {
-        if (adjustedCurrentNode->namespaceURI() == SVGNames::svgNamespaceURI)
-            adjustSVGTagNameCase(*token);
+        if (adjustedCurrentNode.namespaceURI() == SVGNames::svgNamespaceURI)
+            adjustSVGTagNameCase(token);
 
-        if (token->name() == SVGNames::scriptTag && m_tree.currentStackItem()->hasTagName(SVGNames::scriptTag)) {
+        if (token.name() == SVGNames::scriptTag && m_tree.currentStackItem()->hasTagName(SVGNames::scriptTag)) {
             if (scriptingContentIsAllowed(m_tree.parserContentPolicy()))
                 m_scriptToProcess = m_tree.currentElement();
             m_tree.openElements()->pop();
@@ -2961,11 +2916,11 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
         }
         if (!m_tree.currentStackItem()->isInHTMLNamespace()) {
             // FIXME: This code just wants an Element* iterator, instead of an ElementRecord*
-            HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
-            if (!nodeRecord->stackItem()->hasLocalName(token->name()))
+            auto* nodeRecord = m_tree.openElements()->topRecord();
+            if (!nodeRecord->stackItem()->hasLocalName(token.name()))
                 parseError(token);
             while (1) {
-                if (nodeRecord->stackItem()->hasLocalName(token->name())) {
+                if (nodeRecord->stackItem()->hasLocalName(token.name())) {
                     m_tree.openElements()->popUntilPopped(nodeRecord->element());
                     return;
                 }
@@ -2980,10 +2935,10 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
         break;
     }
     case HTMLToken::Comment:
-        m_tree.insertComment(token);
+        m_tree.insertComment(&token);
         return;
     case HTMLToken::Character: {
-        String characters = String(token->characters(), token->charactersLength());
+        String characters = String(token.characters(), token.charactersLength());
         m_tree.insertTextNode(characters);
         if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
             m_framesetOk = false;
@@ -2997,6 +2952,8 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
 
 void HTMLTreeBuilder::finished()
 {
+    ASSERT(!m_destroyed);
+
     if (isParsingFragment())
         return;
 
@@ -3004,12 +2961,11 @@ void HTMLTreeBuilder::finished()
     ASSERT(m_templateInsertionModes.isEmpty());
 #endif
 
-    ASSERT(m_isAttached);
-    // Warning, this may detach the parser. Do not do anything else after this.
     m_tree.finishedParsing();
+    // The tree builder might have been destroyed as an indirect result of finishing the parsing.
 }
 
-void HTMLTreeBuilder::parseError(AtomicHTMLToken*)
+inline void HTMLTreeBuilder::parseError(AtomicHTMLToken&)
 {
 }
 
index ad9fa89..624dfa9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef HTMLTreeBuilder_h
 #define HTMLTreeBuilder_h
 
-#include "FragmentScriptingPermission.h"
 #include "HTMLConstructionSite.h"
-#include "HTMLElementStack.h"
-#include "HTMLFormattingElementList.h"
 #include "HTMLParserOptions.h"
-#include "HTMLStackItem.h"
-#include "HTMLTokenizer.h"
-#include <wtf/Noncopyable.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-#include <wtf/text/StringBuilder.h>
-#include <wtf/text/TextPosition.h>
 
 namespace WebCore {
 
-class AtomicHTMLToken;
-class Document;
-class DocumentFragment;
-class Element;
-class Frame;
-class HTMLToken;
-class HTMLDocument;
-class Node;
 class HTMLDocumentParser;
 
 class HTMLTreeBuilder {
-    WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED;
 public:
-    HTMLTreeBuilder(HTMLDocumentParser&, HTMLDocument&, ParserContentPolicy, const HTMLParserOptions&);
-    HTMLTreeBuilder(HTMLDocumentParser&, DocumentFragment&, Element* contextElement, ParserContentPolicy, const HTMLParserOptions&);
-    ~HTMLTreeBuilder();
+    HTMLTreeBuilder(const HTMLDocumentParser&, HTMLDocument&, ParserContentPolicy, const HTMLParserOptions&);
+    HTMLTreeBuilder(const HTMLDocumentParser&, DocumentFragment&, Element& contextElement, ParserContentPolicy, const HTMLParserOptions&);
+    void setShouldSkipLeadingNewline(bool);
 
-    const HTMLElementStack* openElements() const { return m_tree.openElements(); }
+    ~HTMLTreeBuilder();
 
-    bool isParsingFragment() const { return !!m_fragmentContext.fragment(); }
-#if ENABLE(TEMPLATE_ELEMENT)
-    bool isParsingTemplateContents() const { return m_tree.openElements()->hasTemplateInHTMLScope(); }
-#else
-    bool isParsingTemplateContents() const { return false; }
-#endif
-    bool isParsingFragmentOrTemplateContents() const { return isParsingFragment() || isParsingTemplateContents(); }
+    bool isParsingFragment() const;
 
-    void detach();
+    void constructTree(AtomicHTMLToken&);
 
-    void constructTree(AtomicHTMLToken*);
+    bool hasParserBlockingScript() const;
 
-    bool hasParserBlockingScript() const { return !!m_scriptToProcess; }
     // Must be called to take the parser-blocking script before calling the parser again.
-    PassRefPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
+    RefPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
 
     // Done, close any open tags, etc.
     void finished();
 
-    void setShouldSkipLeadingNewline(bool shouldSkip) { m_shouldSkipLeadingNewline = shouldSkip; }
-
 private:
     class ExternalCharacterTokenBuffer;
+
     // Represents HTML5 "insertion mode"
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
     enum class InsertionMode {
@@ -94,7 +67,9 @@ private:
         InHead,
         InHeadNoscript,
         AfterHead,
+#if ENABLE(TEMPLATE_ELEMENT)
         TemplateContents,
+#endif
         InBody,
         Text,
         InTable,
@@ -113,52 +88,54 @@ private:
         AfterAfterFrameset,
     };
 
-#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+    bool isParsingTemplateContents() const;
+    bool isParsingFragmentOrTemplateContents() const;
+
+#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
     void insertPhoneNumberLink(const String&);
     void linkifyPhoneNumbers(const String&);
 #endif
 
-    void processToken(AtomicHTMLToken*);
-
-    void processDoctypeToken(AtomicHTMLToken*);
-    void processStartTag(AtomicHTMLToken*);
-    void processEndTag(AtomicHTMLToken*);
-    void processComment(AtomicHTMLToken*);
-    void processCharacter(AtomicHTMLToken*);
-    void processEndOfFile(AtomicHTMLToken*);
-
-    bool processStartTagForInHead(AtomicHTMLToken*);
-    void processStartTagForInBody(AtomicHTMLToken*);
-    void processStartTagForInTable(AtomicHTMLToken*);
-    void processEndTagForInBody(AtomicHTMLToken*);
-    void processEndTagForInTable(AtomicHTMLToken*);
-    void processEndTagForInTableBody(AtomicHTMLToken*);
-    void processEndTagForInRow(AtomicHTMLToken*);
-    void processEndTagForInCell(AtomicHTMLToken*);
-
-    void processIsindexStartTagForInBody(AtomicHTMLToken*);
-    void processHtmlStartTagForInBody(AtomicHTMLToken*);
-    bool processBodyEndTagForInBody(AtomicHTMLToken*);
+    void processToken(AtomicHTMLToken&);
+
+    void processDoctypeToken(AtomicHTMLToken&);
+    void processStartTag(AtomicHTMLToken&);
+    void processEndTag(AtomicHTMLToken&);
+    void processComment(AtomicHTMLToken&);
+    void processCharacter(AtomicHTMLToken&);
+    void processEndOfFile(AtomicHTMLToken&);
+
+    bool processStartTagForInHead(AtomicHTMLToken&);
+    void processStartTagForInBody(AtomicHTMLToken&);
+    void processStartTagForInTable(AtomicHTMLToken&);
+    void processEndTagForInBody(AtomicHTMLToken&);
+    void processEndTagForInTable(AtomicHTMLToken&);
+    void processEndTagForInTableBody(AtomicHTMLToken&);
+    void processEndTagForInRow(AtomicHTMLToken&);
+    void processEndTagForInCell(AtomicHTMLToken&);
+
+    void processIsindexStartTagForInBody(AtomicHTMLToken&);
+    void processHtmlStartTagForInBody(AtomicHTMLToken&);
+    bool processBodyEndTagForInBody(AtomicHTMLToken&);
     bool processTableEndTagForInTable();
     bool processCaptionEndTagForInCaption();
     bool processColgroupEndTagForInColumnGroup();
     bool processTrEndTagForInRow();
-    // FIXME: This function should be inlined into its one call site or it
-    // needs to assert which tokens it can be called with.
-    void processAnyOtherEndTagForInBody(AtomicHTMLToken*);
+
+    void processAnyOtherEndTagForInBody(AtomicHTMLToken&);
 
     void processCharacterBuffer(ExternalCharacterTokenBuffer&);
     inline void processCharacterBufferForInBody(ExternalCharacterTokenBuffer&);
 
-    void processFakeStartTag(const QualifiedName&, const Vector<Attribute>& attributes = Vector<Attribute>());
+    void processFakeStartTag(const QualifiedName&, Vector<Attribute>&& attributes = Vector<Attribute>());
     void processFakeEndTag(const QualifiedName&);
     void processFakeEndTag(const AtomicString&);
     void processFakeCharacters(const String&);
     void processFakePEndTagIfPInButtonScope();
 
-    void processGenericRCDATAStartTag(AtomicHTMLToken*);
-    void processGenericRawTextStartTag(AtomicHTMLToken*);
-    void processScriptStartTag(AtomicHTMLToken*);
+    void processGenericRCDATAStartTag(AtomicHTMLToken&);
+    void processGenericRawTextStartTag(AtomicHTMLToken&);
+    void processScriptStartTag(AtomicHTMLToken&);
 
     // Default processing for the different insertion modes.
     void defaultForInitial();
@@ -169,81 +146,104 @@ private:
     void defaultForAfterHead();
     void defaultForInTableText();
 
-    inline bool shouldProcessTokenInForeignContent(AtomicHTMLToken*);
-    void processTokenInForeignContent(AtomicHTMLToken*);
+    bool shouldProcessTokenInForeignContent(AtomicHTMLToken&);
+    void processTokenInForeignContent(AtomicHTMLToken&);
     
-    inline HTMLStackItem* adjustedCurrentStackItem() const;
+    HTMLStackItem& adjustedCurrentStackItem() const;
 
-    Vector<Attribute> attributesForIsindexInput(AtomicHTMLToken*);
+    Vector<Attribute> attributesForIsindexInput(AtomicHTMLToken&);
 
-    void callTheAdoptionAgency(AtomicHTMLToken*);
+    void callTheAdoptionAgency(AtomicHTMLToken&);
 
     void closeTheCell();
 
-    template <bool shouldClose(const HTMLStackItem*)>
-    void processCloseWhenNestedTag(AtomicHTMLToken*);
+    template <bool shouldClose(const HTMLStackItem&)> void processCloseWhenNestedTag(AtomicHTMLToken&);
 
-    void parseError(AtomicHTMLToken*);
-
-    InsertionMode insertionMode() const { return m_insertionMode; }
-    void setInsertionMode(InsertionMode mode) { m_insertionMode = mode; }
+    void parseError(AtomicHTMLToken&);
 
     void resetInsertionModeAppropriately();
 
 #if ENABLE(TEMPLATE_ELEMENT)
-    void processTemplateStartTag(AtomicHTMLToken*);
-    bool processTemplateEndTag(AtomicHTMLToken*);
-    bool processEndOfFileForInTemplateContents(AtomicHTMLToken*);
+    void processTemplateStartTag(AtomicHTMLToken&);
+    bool processTemplateEndTag(AtomicHTMLToken&);
+    bool processEndOfFileForInTemplateContents(AtomicHTMLToken&);
 #endif
 
     class FragmentParsingContext {
-        WTF_MAKE_NONCOPYABLE(FragmentParsingContext);
     public:
         FragmentParsingContext();
-        FragmentParsingContext(DocumentFragment&, Element* contextElement);
-        ~FragmentParsingContext();
+        FragmentParsingContext(DocumentFragment&, Element& contextElement);
 
-        DocumentFragment* fragment() const { return m_fragment; }
-        Element* contextElement() const { ASSERT(m_fragment); return m_contextElementStackItem->element(); }
-        HTMLStackItem* contextElementStackItem() const { ASSERT(m_fragment); return m_contextElementStackItem.get(); }
+        DocumentFragment* fragment() const;
+        Element& contextElement() const;
+        HTMLStackItem& contextElementStackItem() const;
 
     private:
-        DocumentFragment* m_fragment;
+        DocumentFragment* m_fragment { nullptr };
         RefPtr<HTMLStackItem> m_contextElementStackItem;
     };
 
-    bool m_framesetOk;
-#ifndef NDEBUG
-    bool m_isAttached;
-#endif
-    FragmentParsingContext m_fragmentContext;
-    HTMLConstructionSite m_tree;
-
-    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
-    InsertionMode m_insertionMode;
+    const HTMLDocumentParser& m_parser;
+    const HTMLParserOptions m_options;
+    const FragmentParsingContext m_fragmentContext;
 
-    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#original-insertion-mode
-    InsertionMode m_originalInsertionMode;
+    HTMLConstructionSite m_tree;
 
+    // https://html.spec.whatwg.org/multipage/syntax.html#the-insertion-mode
+    InsertionMode m_insertionMode { InsertionMode::Initial };
+    InsertionMode m_originalInsertionMode { InsertionMode::Initial };
 #if ENABLE(TEMPLATE_ELEMENT)
-    Vector<InsertionMode> m_templateInsertionModes;
+    Vector<InsertionMode, 1> m_templateInsertionModes;
 #endif
 
-    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#pending-table-character-tokens
+    // https://html.spec.whatwg.org/multipage/syntax.html#concept-pending-table-char-tokens
     StringBuilder m_pendingTableCharacters;
 
-    bool m_shouldSkipLeadingNewline;
-
-    // We access parser because HTML5 spec requires that we be able to change the state of the tokenizer
-    // from within parser actions. We also need it to track the current position.
-    HTMLDocumentParser& m_parser;
-
     RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
     TextPosition m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
 
-    HTMLParserOptions m_options;
+    bool m_shouldSkipLeadingNewline { false };
+
+    bool m_framesetOk { true };
+
+#if !ASSERT_DISABLED
+    bool m_destroyed { false };
+    bool m_destructionProhibited { true };
+#endif
 };
 
+inline HTMLTreeBuilder::~HTMLTreeBuilder()
+{
+#if !ASSERT_DISABLED
+    ASSERT(!m_destroyed);
+    ASSERT(!m_destructionProhibited);
+    m_destroyed = true;
+#endif
+}
+
+inline void HTMLTreeBuilder::setShouldSkipLeadingNewline(bool shouldSkip)
+{
+    ASSERT(!m_destroyed);
+    m_shouldSkipLeadingNewline = shouldSkip;
+}
+
+inline bool HTMLTreeBuilder::isParsingFragment() const
+{
+    ASSERT(!m_destroyed);
+    return !!m_fragmentContext.fragment();
+}
+
+inline bool HTMLTreeBuilder::hasParserBlockingScript() const
+{
+    ASSERT(!m_destroyed);
+    return !!m_scriptToProcess;
+}
+
+inline DocumentFragment* HTMLTreeBuilder::FragmentParsingContext::fragment() const
+{
+    return m_fragment;
+}
+
 }
 
 #endif
index b2736f3..f6a5676 100644 (file)
@@ -59,7 +59,7 @@ void TextDocumentParser::insertFakePreElement()
     Vector<Attribute> attributes;
     attributes.append(Attribute(styleAttr, "word-wrap: break-word; white-space: pre-wrap;"));
     AtomicHTMLToken fakePre(HTMLToken::StartTag, preTag.localName(), attributes);
-    treeBuilder()->constructTree(&fakePre);
+    treeBuilder()->constructTree(fakePre);
 
     // Normally we would skip the first \n after a <pre> element, but we don't
     // want to skip the first \n for text documents!