From 21e7dce1a253c44c62e2cc1233cec8af85c10ed8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 22 Oct 2017 08:50:25 +1100 Subject: [PATCH] Bug 1410294 (part 3) - Overhaul static atom macros. r=froydnj. There are four things that must be provided for every static atom, two of which have a macro: - the atom pointer declaration (no macro); - the atom pointer definition (no macro); - the atom char buffer (NS_STATIC_ATOM_BUFFER); - the StaticAtomSetup struct (NS_STATIC_ATOM_SETUP). This patch introduces new macros for the first two things: NS_STATIC_ATOM_DECL and NS_STATIC_ATOM_DEFN, and changes the arguments of the existing two macros to make them easier to use (e.g. all the '##' concatenation now happens within the macros). One consequence of the change is that all static atoms must be within a class, so the patch adds a couple of classes where necessary (DefaultAtoms, TSAtoms). The patch also adds a big comment explaining how the macros are used, and what their expansion looks like. This makes it a lot easier to understand how static atoms work. Correspondingly, the patch removes some small comments scattered around the macro use points. MozReview-Commit-ID: wpRyrEOTHE --HG-- extra : rebase_source : 9f85d477b4d06c9a9e710c757de1f1476edb6efe --- dom/base/nsGkAtoms.cpp | 17 +--- dom/base/nsGkAtoms.h | 25 ++--- editor/txtsvc/nsTextServicesDocument.cpp | 85 +++++++++-------- editor/txtsvc/nsTextServicesDocument.h | 4 - layout/style/moz.build | 8 +- layout/style/nsCSSAnonBoxes.cpp | 30 +++--- layout/style/nsCSSAnonBoxes.h | 4 +- layout/style/nsCSSPseudoClasses.cpp | 81 ++++++++-------- layout/style/nsCSSPseudoElements.cpp | 13 ++- layout/style/nsCSSPseudoElements.h | 5 +- parser/htmlparser/nsHTMLTags.cpp | 38 ++++---- parser/htmlparser/nsHTMLTags.h | 4 +- rdf/base/nsRDFContentSink.cpp | 17 ++-- xpcom/ds/nsAtomTable.cpp | 20 +++- xpcom/ds/nsStaticAtom.h | 115 ++++++++++++++++++++--- xpcom/io/nsDirectoryService.cpp | 11 ++- xpcom/io/nsDirectoryService.h | 11 +-- 17 files changed, 286 insertions(+), 202 deletions(-) diff --git a/dom/base/nsGkAtoms.cpp b/dom/base/nsGkAtoms.cpp index 168877db7089..87d04c36989a 100644 --- a/dom/base/nsGkAtoms.cpp +++ b/dom/base/nsGkAtoms.cpp @@ -4,30 +4,23 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* - * This class wraps up the creation (and destruction) of the standard - * set of atoms used by gklayout; the atoms are created when gklayout - * is loaded and they are destroyed when gklayout is unloaded. - */ - #include "nsGkAtoms.h" #include "nsStaticAtom.h" using namespace mozilla; -// define storage for all atoms -#define GK_ATOM(name_, value_) nsAtom* nsGkAtoms::name_; +#define GK_ATOM(name_, value_) NS_STATIC_ATOM_DEFN(nsGkAtoms, name_) #include "nsGkAtomList.h" #undef GK_ATOM -#define GK_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_) +#define GK_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_, value_) #include "nsGkAtomList.h" #undef GK_ATOM static const nsStaticAtomSetup sGkAtomSetup[] = { -#define GK_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(name_##_buffer, &nsGkAtoms::name_), -#include "nsGkAtomList.h" -#undef GK_ATOM + #define GK_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(nsGkAtoms, name_) + #include "nsGkAtomList.h" + #undef GK_ATOM }; void nsGkAtoms::AddRefAtoms() diff --git a/dom/base/nsGkAtoms.h b/dom/base/nsGkAtoms.h index aee547ed23b8..fb7f5bd71ebb 100644 --- a/dom/base/nsGkAtoms.h +++ b/dom/base/nsGkAtoms.h @@ -4,32 +4,19 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* - * This class wraps up the creation (and destruction) of the standard - * set of atoms used by gklayout; the atoms are created when gklayout - * is loaded and they are destroyed when gklayout is unloaded. - */ - #ifndef nsGkAtoms_h___ #define nsGkAtoms_h___ -class nsAtom; +#include "nsStaticAtom.h" -class nsGkAtoms { +class nsGkAtoms +{ public: - static void AddRefAtoms(); - /* Declare all atoms - - The atom names and values are stored in nsGkAtomList.h and - are brought to you by the magic of C preprocessing - - Add new atoms to nsGkAtomList and all support logic will be auto-generated - */ -#define GK_ATOM(_name, _value) static nsAtom* _name; -#include "nsGkAtomList.h" -#undef GK_ATOM + #define GK_ATOM(_name, _value) NS_STATIC_ATOM_DECL(_name) + #include "nsGkAtomList.h" + #undef GK_ATOM }; #endif /* nsGkAtoms_h___ */ diff --git a/editor/txtsvc/nsTextServicesDocument.cpp b/editor/txtsvc/nsTextServicesDocument.cpp index 7cc326036013..ec95ca605826 100644 --- a/editor/txtsvc/nsTextServicesDocument.cpp +++ b/editor/txtsvc/nsTextServicesDocument.cpp @@ -76,10 +76,6 @@ public: bool mIsValid; }; -#define TS_ATOM(name_, value_) nsAtom* nsTextServicesDocument::name_ = 0; -#include "nsTSAtomList.h" // IWYU pragma: keep -#undef TS_ATOM - nsTextServicesDocument::nsTextServicesDocument() { mSelStartIndex = -1; @@ -95,20 +91,31 @@ nsTextServicesDocument::~nsTextServicesDocument() ClearOffsetTable(&mOffsetTable); } -#define TS_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_) +class TSAtoms +{ +public: + #define TS_ATOM(name_, value_) NS_STATIC_ATOM_DECL(name_) + #include "nsTSAtomList.h" // IWYU pragma: keep + #undef TS_ATOM +}; + +#define TS_ATOM(name_, value_) NS_STATIC_ATOM_DEFN(TSAtoms, name_) #include "nsTSAtomList.h" // IWYU pragma: keep #undef TS_ATOM -/* static */ -void +#define TS_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_, value_) +#include "nsTSAtomList.h" // IWYU pragma: keep +#undef TS_ATOM + +static const nsStaticAtomSetup sTSAtomSetup[] = { + #define TS_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(TSAtoms, name_) + #include "nsTSAtomList.h" // IWYU pragma: keep + #undef TS_ATOM +}; + +/* static */ void nsTextServicesDocument::RegisterAtoms() { - static const nsStaticAtomSetup sTSAtomSetup[] = { -#define TS_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(name_##_buffer, &name_), -#include "nsTSAtomList.h" // IWYU pragma: keep -#undef TS_ATOM - }; - NS_RegisterStaticAtoms(sTSAtomSetup); } @@ -2040,32 +2047,32 @@ nsTextServicesDocument::IsBlockNode(nsIContent *aContent) nsAtom *atom = aContent->NodeInfo()->NameAtom(); - return (sAAtom != atom && - sAddressAtom != atom && - sBigAtom != atom && - sBAtom != atom && - sCiteAtom != atom && - sCodeAtom != atom && - sDfnAtom != atom && - sEmAtom != atom && - sFontAtom != atom && - sIAtom != atom && - sKbdAtom != atom && - sKeygenAtom != atom && - sNobrAtom != atom && - sSAtom != atom && - sSampAtom != atom && - sSmallAtom != atom && - sSpacerAtom != atom && - sSpanAtom != atom && - sStrikeAtom != atom && - sStrongAtom != atom && - sSubAtom != atom && - sSupAtom != atom && - sTtAtom != atom && - sUAtom != atom && - sVarAtom != atom && - sWbrAtom != atom); + return (TSAtoms::sAAtom != atom && + TSAtoms::sAddressAtom != atom && + TSAtoms::sBigAtom != atom && + TSAtoms::sBAtom != atom && + TSAtoms::sCiteAtom != atom && + TSAtoms::sCodeAtom != atom && + TSAtoms::sDfnAtom != atom && + TSAtoms::sEmAtom != atom && + TSAtoms::sFontAtom != atom && + TSAtoms::sIAtom != atom && + TSAtoms::sKbdAtom != atom && + TSAtoms::sKeygenAtom != atom && + TSAtoms::sNobrAtom != atom && + TSAtoms::sSAtom != atom && + TSAtoms::sSampAtom != atom && + TSAtoms::sSmallAtom != atom && + TSAtoms::sSpacerAtom != atom && + TSAtoms::sSpanAtom != atom && + TSAtoms::sStrikeAtom != atom && + TSAtoms::sStrongAtom != atom && + TSAtoms::sSubAtom != atom && + TSAtoms::sSupAtom != atom && + TSAtoms::sTtAtom != atom && + TSAtoms::sUAtom != atom && + TSAtoms::sVarAtom != atom && + TSAtoms::sWbrAtom != atom); } bool diff --git a/editor/txtsvc/nsTextServicesDocument.h b/editor/txtsvc/nsTextServicesDocument.h index 6f8872a27f7f..9a2aecb88ed1 100644 --- a/editor/txtsvc/nsTextServicesDocument.h +++ b/editor/txtsvc/nsTextServicesDocument.h @@ -36,10 +36,6 @@ class nsTextServicesDocument final : public nsITextServicesDocument, public nsIEditActionListener { private: - #define TS_ATOM(name_, value_) static nsAtom* name_; - #include "nsTSAtomList.h" // IWYU pragma: keep - #undef TS_ATOM - typedef enum { eIsDone=0, // No iterator (I), or iterator doesn't point to anything valid. eValid, // I points to first text node (TN) in current block (CB). ePrev, // No TN in CB, I points to first TN in prev block. diff --git a/layout/style/moz.build b/layout/style/moz.build index 10529f067d1f..c7486a7b8d91 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -218,7 +218,6 @@ UNIFIED_SOURCES += [ 'nsCSSParser.cpp', 'nsCSSProps.cpp', 'nsCSSPseudoClasses.cpp', - 'nsCSSPseudoElements.cpp', 'nsCSSRuleProcessor.cpp', 'nsCSSRules.cpp', 'nsCSSScanner.cpp', @@ -277,9 +276,12 @@ UNIFIED_SOURCES += [ 'URLExtraData.cpp', ] -# - nsLayoutStylesheetCache.cpp needs to be built separately because it uses -# nsExceptionHandler.h, which includes windows.h. SOURCES += [ + # Both nsCSSPseudoElements.cpp and nsCSSPseudoClasses.cpp defined a + # 'mozPlaceholder' static atom. + 'nsCSSPseudoElements.cpp', + # nsLayoutStylesheetCache.cpp uses nsExceptionHandler.h, which includes + # windows.h. 'nsLayoutStylesheetCache.cpp', ] diff --git a/layout/style/nsCSSAnonBoxes.cpp b/layout/style/nsCSSAnonBoxes.cpp index 454cababa669..890d041255be 100644 --- a/layout/style/nsCSSAnonBoxes.cpp +++ b/layout/style/nsCSSAnonBoxes.cpp @@ -13,32 +13,30 @@ using namespace mozilla; -// define storage for all atoms #define CSS_ANON_BOX(name_, value_) \ - nsICSSAnonBoxPseudo* nsCSSAnonBoxes::name_; + NS_STATIC_ATOM_SUBCLASS_DEFN(nsICSSAnonBoxPseudo, nsCSSAnonBoxes, name_) #include "nsCSSAnonBoxList.h" #undef CSS_ANON_BOX -#define CSS_ANON_BOX(name_, value_) \ - NS_STATIC_ATOM_BUFFER(name_##_buffer, value_) +#define CSS_ANON_BOX(name_, value_) NS_STATIC_ATOM_BUFFER(name_, value_) #include "nsCSSAnonBoxList.h" #undef CSS_ANON_BOX static const nsStaticAtomSetup sCSSAnonBoxAtomSetup[] = { // Put the non-inheriting anon boxes first, so we can index into them easily. -#define CSS_ANON_BOX(name_, value_) /* nothing */ -#define CSS_NON_INHERITING_ANON_BOX(name_, value_) \ - NS_STATIC_ATOM_SETUP(name_##_buffer, (nsAtom**)&nsCSSAnonBoxes::name_), -#include "nsCSSAnonBoxList.h" -#undef CSS_NON_INHERITING_ANON_BOX -#undef CSS_ANON_BOX + #define CSS_ANON_BOX(name_, value_) /* nothing */ + #define CSS_NON_INHERITING_ANON_BOX(name_, value_) \ + NS_STATIC_ATOM_SUBCLASS_SETUP(nsCSSAnonBoxes, name_) + #include "nsCSSAnonBoxList.h" + #undef CSS_NON_INHERITING_ANON_BOX + #undef CSS_ANON_BOX -#define CSS_ANON_BOX(name_, value_) \ - NS_STATIC_ATOM_SETUP(name_##_buffer, (nsAtom**)&nsCSSAnonBoxes::name_), -#define CSS_NON_INHERITING_ANON_BOX(name_, value_) /* nothing */ -#include "nsCSSAnonBoxList.h" -#undef CSS_NON_INHERITING_ANON_BOX -#undef CSS_ANON_BOX + #define CSS_ANON_BOX(name_, value_) \ + NS_STATIC_ATOM_SUBCLASS_SETUP(nsCSSAnonBoxes, name_) + #define CSS_NON_INHERITING_ANON_BOX(name_, value_) /* nothing */ + #include "nsCSSAnonBoxList.h" + #undef CSS_NON_INHERITING_ANON_BOX + #undef CSS_ANON_BOX }; void nsCSSAnonBoxes::AddRefAtoms() diff --git a/layout/style/nsCSSAnonBoxes.h b/layout/style/nsCSSAnonBoxes.h index cbbe904a1190..287d82c470a2 100644 --- a/layout/style/nsCSSAnonBoxes.h +++ b/layout/style/nsCSSAnonBoxes.h @@ -9,6 +9,7 @@ #define nsCSSAnonBoxes_h___ #include "nsAtom.h" +#include "nsStaticAtom.h" // Empty class derived from nsAtom so that function signatures can // require an atom from this atom list. @@ -29,7 +30,8 @@ public: aPseudo == firstLetterContinuation; } -#define CSS_ANON_BOX(_name, _value) static nsICSSAnonBoxPseudo* _name; +#define CSS_ANON_BOX(name_, value_) \ + NS_STATIC_ATOM_SUBCLASS_DECL(nsICSSAnonBoxPseudo, name_) #include "nsCSSAnonBoxList.h" #undef CSS_ANON_BOX diff --git a/layout/style/nsCSSPseudoClasses.cpp b/layout/style/nsCSSPseudoClasses.cpp index 2098a3df624f..250915a5c2ff 100644 --- a/layout/style/nsCSSPseudoClasses.cpp +++ b/layout/style/nsCSSPseudoClasses.cpp @@ -18,17 +18,6 @@ using namespace mozilla; -// define storage for all atoms -#define CSS_PSEUDO_CLASS(_name, _value, _flags, _pref) \ - static nsAtom* sPseudoClass_##_name; -#include "nsCSSPseudoClassList.h" -#undef CSS_PSEUDO_CLASS - -#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ - NS_STATIC_ATOM_BUFFER(name_##_pseudo_class_buffer, value_) -#include "nsCSSPseudoClassList.h" -#undef CSS_PSEUDO_CLASS - #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ static_assert(!((flags_) & CSS_PSEUDO_CLASS_ENABLED_IN_CHROME) || \ ((flags_) & CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), \ @@ -37,12 +26,30 @@ using namespace mozilla; #include "nsCSSPseudoClassList.h" #undef CSS_PSEUDO_CLASS -// Array of nsStaticAtomSetup for each of the pseudo-classes. -static const nsStaticAtomSetup sCSSPseudoClassAtomSetup[] = { +class CSSPseudoClassAtoms +{ +public: + #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ + NS_STATIC_ATOM_DECL(name_) + #include "nsCSSPseudoClassList.h" + #undef CSS_PSEUDO_CLASS +}; + #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ - NS_STATIC_ATOM_SETUP(name_##_pseudo_class_buffer, &sPseudoClass_##name_), + NS_STATIC_ATOM_DEFN(CSSPseudoClassAtoms, name_) #include "nsCSSPseudoClassList.h" #undef CSS_PSEUDO_CLASS + +#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ + NS_STATIC_ATOM_BUFFER(name_, value_) +#include "nsCSSPseudoClassList.h" +#undef CSS_PSEUDO_CLASS + +static const nsStaticAtomSetup sCSSPseudoClassAtomSetup[] = { + #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ + NS_STATIC_ATOM_SETUP(CSSPseudoClassAtoms, name_) + #include "nsCSSPseudoClassList.h" + #undef CSS_PSEUDO_CLASS }; // Flags data for each of the pseudo-classes, which must be separate @@ -50,39 +57,39 @@ static const nsStaticAtomSetup sCSSPseudoClassAtomSetup[] = { // nsStaticAtomSetup. /* static */ const uint32_t nsCSSPseudoClasses::kPseudoClassFlags[] = { -#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ - flags_, -#include "nsCSSPseudoClassList.h" -#undef CSS_PSEUDO_CLASS + #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ + flags_, + #include "nsCSSPseudoClassList.h" + #undef CSS_PSEUDO_CLASS }; /* static */ bool nsCSSPseudoClasses::sPseudoClassEnabled[] = { -// If the pseudo class has any "ENABLED_IN" flag set, it is disabled by -// default. Note that, if a pseudo class has pref, whatever its default -// value is, it'll later be changed in nsCSSPseudoClasses::AddRefAtoms() -// If the pseudo class has "ENABLED_IN" flags but doesn't have a pref, -// it is an internal pseudo class which is disabled elsewhere. -#define IS_ENABLED_BY_DEFAULT(flags_) \ - (!((flags_) & CSS_PSEUDO_CLASS_ENABLED_MASK)) -#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ - IS_ENABLED_BY_DEFAULT(flags_), -#include "nsCSSPseudoClassList.h" -#undef CSS_PSEUDO_CLASS -#undef IS_ENABLED_BY_DEFAULT + // If the pseudo class has any "ENABLED_IN" flag set, it is disabled by + // default. Note that, if a pseudo class has pref, whatever its default + // value is, it'll later be changed in nsCSSPseudoClasses::AddRefAtoms() + // If the pseudo class has "ENABLED_IN" flags but doesn't have a pref, + // it is an internal pseudo class which is disabled elsewhere. + #define IS_ENABLED_BY_DEFAULT(flags_) \ + (!((flags_) & CSS_PSEUDO_CLASS_ENABLED_MASK)) + #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ + IS_ENABLED_BY_DEFAULT(flags_), + #include "nsCSSPseudoClassList.h" + #undef CSS_PSEUDO_CLASS + #undef IS_ENABLED_BY_DEFAULT }; void nsCSSPseudoClasses::AddRefAtoms() { NS_RegisterStaticAtoms(sCSSPseudoClassAtomSetup); -#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ - if (pref_[0]) { \ - auto idx = static_cast(Type::name_); \ - Preferences::AddBoolVarCache(&sPseudoClassEnabled[idx], pref_); \ - } -#include "nsCSSPseudoClassList.h" -#undef CSS_PSEUDO_CLASS + #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \ + if (pref_[0]) { \ + auto idx = static_cast(Type::name_); \ + Preferences::AddBoolVarCache(&sPseudoClassEnabled[idx], pref_); \ + } + #include "nsCSSPseudoClassList.h" + #undef CSS_PSEUDO_CLASS } bool diff --git a/layout/style/nsCSSPseudoElements.cpp b/layout/style/nsCSSPseudoElements.cpp index 17d2266f8896..e5b72787c0a7 100644 --- a/layout/style/nsCSSPseudoElements.cpp +++ b/layout/style/nsCSSPseudoElements.cpp @@ -16,23 +16,22 @@ using namespace mozilla; -// define storage for all atoms #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ - nsICSSPseudoElement* nsCSSPseudoElements::name_; + NS_STATIC_ATOM_BUFFER(name_, value_) #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ - NS_STATIC_ATOM_BUFFER(name_##_pseudo_element_buffer, value_) + NS_STATIC_ATOM_SUBCLASS_DEFN(nsICSSPseudoElement, nsCSSPseudoElements, name_) #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT // Array of nsStaticAtomSetup for each of the pseudo-elements. static const nsStaticAtomSetup sCSSPseudoElementAtomSetup[] = { -#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ - NS_STATIC_ATOM_SETUP(name_##_pseudo_element_buffer, (nsAtom**)&nsCSSPseudoElements::name_), -#include "nsCSSPseudoElementList.h" -#undef CSS_PSEUDO_ELEMENT + #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ + NS_STATIC_ATOM_SUBCLASS_SETUP(nsCSSPseudoElements, name_) + #include "nsCSSPseudoElementList.h" + #undef CSS_PSEUDO_ELEMENT }; // Flags data for each of the pseudo-elements, which must be separate diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index 515deddd993e..02d6def71636 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -9,6 +9,7 @@ #define nsCSSPseudoElements_h___ #include "nsAtom.h" +#include "nsStaticAtom.h" #include "mozilla/CSSEnabledState.h" #include "mozilla/Compiler.h" @@ -54,7 +55,7 @@ typedef uint8_t CSSPseudoElementTypeBase; enum class CSSPseudoElementType : CSSPseudoElementTypeBase { // If the actual pseudo-elements stop being first here, change // GetPseudoType. -#define CSS_PSEUDO_ELEMENT(_name, _value_, _flags) \ +#define CSS_PSEUDO_ELEMENT(_name, _value, _flags) \ _name, #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT @@ -96,7 +97,7 @@ public: } #define CSS_PSEUDO_ELEMENT(_name, _value, _flags) \ - static nsICSSPseudoElement* _name; + NS_STATIC_ATOM_SUBCLASS_DECL(nsICSSPseudoElement, _name) #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT diff --git a/parser/htmlparser/nsHTMLTags.cpp b/parser/htmlparser/nsHTMLTags.cpp index 92d36be43f1f..5db3e4bfe261 100644 --- a/parser/htmlparser/nsHTMLTags.cpp +++ b/parser/htmlparser/nsHTMLTags.cpp @@ -23,14 +23,10 @@ const char16_t* const nsHTMLTags::sTagUnicodeTable[] = { #undef HTML_TAG #undef HTML_OTHER -// static array of tag atoms -nsAtom* nsHTMLTags::sTagAtomTable[eHTMLTag_userdefined - 1]; - int32_t nsHTMLTags::gTableRefCount; PLHashTable* nsHTMLTags::gTagTable; PLHashTable* nsHTMLTags::gTagAtomTable; - // char16_t* -> id hash static PLHashNumber HTMLTagsHashCodeUCPtr(const void *key) @@ -56,29 +52,31 @@ HTMLTagsHashCodeAtom(const void *key) #define NS_HTMLTAG_NAME_MAX_LENGTH 10 -// static -void +// This would use NS_STATIC_ATOM_DEFN if it wasn't an array. +nsAtom* nsHTMLTags::sTagAtomTable[eHTMLTag_userdefined - 1]; + +#define HTML_TAG(_tag, _classname, _interfacename) \ + NS_STATIC_ATOM_BUFFER(_tag, #_tag) +#define HTML_OTHER(_tag) +#include "nsHTMLTagList.h" +#undef HTML_TAG +#undef HTML_OTHER + +/* static */ void nsHTMLTags::RegisterAtoms(void) { -#define HTML_TAG(_tag, _classname, _interfacename) NS_STATIC_ATOM_BUFFER(Atombuffer_##_tag, #_tag) -#define HTML_OTHER(_tag) -#include "nsHTMLTagList.h" -#undef HTML_TAG -#undef HTML_OTHER - -// static array of tag StaticAtom structs -#define HTML_TAG(_tag, _classname, _interfacename) NS_STATIC_ATOM_SETUP(Atombuffer_##_tag, &nsHTMLTags::sTagAtomTable[eHTMLTag_##_tag - 1]), -#define HTML_OTHER(_tag) + // This would use NS_STATIC_ATOM_SETUP if it wasn't an array. static const nsStaticAtomSetup sTagAtomSetup[] = { -#include "nsHTMLTagList.h" + #define HTML_TAG(_tag, _classname, _interfacename) \ + { _tag##_buffer, &nsHTMLTags::sTagAtomTable[eHTMLTag_##_tag - 1] }, + #define HTML_OTHER(_tag) + #include "nsHTMLTagList.h" + #undef HTML_TAG + #undef HTML_OTHER }; -#undef HTML_TAG -#undef HTML_OTHER - // Fill in our static atom pointers NS_RegisterStaticAtoms(sTagAtomSetup); - #if defined(DEBUG) { // let's verify that all names in the the table are lowercase... diff --git a/parser/htmlparser/nsHTMLTags.h b/parser/htmlparser/nsHTMLTags.h index 80e944dbd8d9..7a3760cf3aee 100644 --- a/parser/htmlparser/nsHTMLTags.h +++ b/parser/htmlparser/nsHTMLTags.h @@ -6,11 +6,10 @@ #ifndef nsHTMLTags_h___ #define nsHTMLTags_h___ +#include "nsStaticAtom.h" #include "nsString.h" #include "plhash.h" -class nsAtom; - /* Declare the enum list using the magic of preprocessing enum values are "eHTMLTag_foo" (where foo is the tag) @@ -76,6 +75,7 @@ public: #endif private: + // This would use NS_STATIC_ATOM_DECL if it wasn't an array. static nsAtom* sTagAtomTable[eHTMLTag_userdefined - 1]; static const char16_t* const sTagUnicodeTable[]; diff --git a/rdf/base/nsRDFContentSink.cpp b/rdf/base/nsRDFContentSink.cpp index b52916d85882..7dbbd71d3de6 100644 --- a/rdf/base/nsRDFContentSink.cpp +++ b/rdf/base/nsRDFContentSink.cpp @@ -126,9 +126,9 @@ public: static nsIRDFResource* kRDF_Seq; static nsIRDFResource* kRDF_nextVal; -#define RDF_ATOM(name_, value_) static nsAtom* name_; -#include "nsRDFContentSinkAtomList.h" -#undef RDF_ATOM + #define RDF_ATOM(name_, value_) NS_STATIC_ATOM_DECL(name_) + #include "nsRDFContentSinkAtomList.h" + #undef RDF_ATOM typedef struct ContainerInfo { nsIRDFResource** mType; @@ -235,18 +235,19 @@ mozilla::LazyLogModule RDFContentSinkImpl::gLog("nsRDFContentSink"); //////////////////////////////////////////////////////////////////////// -#define RDF_ATOM(name_, value_) nsAtom* RDFContentSinkImpl::name_; +#define RDF_ATOM(name_, value_) NS_STATIC_ATOM_DEFN(RDFContentSinkImpl, name_) #include "nsRDFContentSinkAtomList.h" #undef RDF_ATOM -#define RDF_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_) +#define RDF_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_, value_) #include "nsRDFContentSinkAtomList.h" #undef RDF_ATOM static const nsStaticAtomSetup sRDFContentSinkAtomSetup[] = { -#define RDF_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(name_##_buffer, &RDFContentSinkImpl::name_), -#include "nsRDFContentSinkAtomList.h" -#undef RDF_ATOM + #define RDF_ATOM(name_, value_) \ + NS_STATIC_ATOM_SETUP(RDFContentSinkImpl, name_) + #include "nsRDFContentSinkAtomList.h" + #undef RDF_ATOM }; // static diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 294484b876a5..247943604995 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -13,6 +13,7 @@ #include "mozilla/Sprintf.h" #include "mozilla/Unused.h" +#include "nsAtom.h" #include "nsAtomTable.h" #include "nsStaticAtom.h" #include "nsString.h" @@ -482,6 +483,20 @@ static bool gStaticAtomTableSealed = false; // shrinking. #define ATOM_HASHTABLE_INITIAL_LENGTH 4096 +class DefaultAtoms +{ +public: + NS_STATIC_ATOM_DECL(empty) +}; + +NS_STATIC_ATOM_DEFN(DefaultAtoms, empty) + +NS_STATIC_ATOM_BUFFER(empty, "") + +static const nsStaticAtomSetup sDefaultAtomSetup[] = { + NS_STATIC_ATOM_SETUP(DefaultAtoms, empty) +}; + void NS_InitAtomTable() { @@ -496,11 +511,6 @@ NS_InitAtomTable() // static atom. In order to avoid that, we register an empty string static // atom as soon as we initialize the atom table to guarantee that the empty // string atom will always be static. - NS_STATIC_ATOM_BUFFER(empty, ""); - static nsAtom* empty_atom = nullptr; - static const nsStaticAtomSetup sDefaultAtomSetup[] = { - NS_STATIC_ATOM_SETUP(empty, &empty_atom) - }; NS_RegisterStaticAtoms(sDefaultAtomSetup); } diff --git a/xpcom/ds/nsStaticAtom.h b/xpcom/ds/nsStaticAtom.h index 3408ef4c63ec..cddcb92c26a4 100644 --- a/xpcom/ds/nsStaticAtom.h +++ b/xpcom/ds/nsStaticAtom.h @@ -7,31 +7,116 @@ #ifndef nsStaticAtom_h__ #define nsStaticAtom_h__ -#include "nsAtom.h" -#include "nsStringBuffer.h" +#include -#define NS_STATIC_ATOM_SETUP(buffer_name, atom_ptr) \ - { buffer_name, atom_ptr } +class nsAtom; -// Note that |str_data| is an 8-bit string, and so |sizeof(str_data)| is equal +// The following macros are used to define static atoms, typically in +// conjunction with a .h file that defines the names and values of the atoms. +// +// For example, the .h file might be called MyAtomList.h and look like this: +// +// MY_ATOM(one, "one") +// MY_ATOM(two, "two") +// MY_ATOM(three, "three") +// +// The code defining the static atoms might look like this: +// +// class MyAtoms { +// public: +// #define MY_ATOM(_name, _value) NS_STATIC_ATOM_DECL(_name) +// #include "MyAtomList.h" +// #undef MY_ATOM +// }; +// +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DEFN(MyAtoms, name_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_, value_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// +// static const nsStaticAtomSetup sMyAtomSetup[] = { +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(MyAtoms, name_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// }; +// +// The macros expand to the following: +// +// class MyAtoms +// { +// public: +// static nsAtom* one; +// static nsAtom* two; +// static nsAtom* three; +// }; +// +// nsAtom* MyAtoms::one; +// nsAtom* MyAtoms::two; +// nsAtom* MyAtoms::three; +// +// static const char16_t one_buffer[4] = u"one"; // plus a static_assert +// static const char16_t two_buffer[4] = u"two"; // plus a static_assert +// static const char16_t three_buffer[6] = u"three"; // plus a static_assert +// +// static const nsStaticAtomSetup sMyAtomSetup[] = { +// { one_buffer, &MyAtoms::one }, +// { two_buffer, &MyAtoms::two }, +// { three_buffer, &MyAtoms::three }, +// }; +// +// When RegisterStaticAtoms(sMyAtomSetup) is called it iterates over +// sMyAtomSetup[]. E.g. for the first atom it does roughly the following: +// - MyAtoms::one = new nsAtom(one_buffer) +// - inserts MyAtoms::one into the atom table + +// The declaration of the pointer to the static atom, which must be within a +// class. +#define NS_STATIC_ATOM_DECL(name_) \ + static nsAtom* name_; + +// Like NS_STATIC_ATOM_DECL, but for sub-classes of nsAtom. +#define NS_STATIC_ATOM_SUBCLASS_DECL(type_, name_) \ + static type_* name_; + +// The definition of the pointer to the static atom. Initially null, it is +// set by RegisterStaticAtoms() to point to a heap-allocated nsAtom. +#define NS_STATIC_ATOM_DEFN(class_, name_) \ + nsAtom* class_::name_; + +// Like NS_STATIC_ATOM_DEFN, but for sub-classes of nsAtom. +#define NS_STATIC_ATOM_SUBCLASS_DEFN(type_, class_, name_) \ + type_* class_::name_; + +// The buffer of 16-bit chars that constitute the static atom. +// +// Note that |value_| is an 8-bit string, and so |sizeof(value_)| is equal // to the number of chars (including the terminating '\0'). The |u""| prefix -// converts |str_data| to a 16-bit string, which is assigned. -#define NS_STATIC_ATOM_BUFFER(buffer_name, str_data) \ - static const char16_t buffer_name[sizeof(str_data)] = u"" str_data; \ - static_assert(sizeof(str_data[0]) == 1, "non-8-bit static atom literal"); +// converts |value_| to a 16-bit string, which is what is assigned. +#define NS_STATIC_ATOM_BUFFER(name_, value_) \ + static const char16_t name_##_buffer[sizeof(value_)] = u"" value_; \ + static_assert(sizeof(value_[0]) == 1, "non-8-bit static atom literal"); -/** - * Holds data used to initialize large number of atoms during startup. Use - * the above macros to initialize these structs. They should never be accessed - * directly other than from AtomTable.cpp. - */ +// The StaticAtomSetup. Used only during start-up. +#define NS_STATIC_ATOM_SETUP(class_, name_) \ + { name_##_buffer, &class_::name_ }, + +// Like NS_STATIC_ATOM_SUBCLASS, but for sub-classes of nsAtom. +#define NS_STATIC_ATOM_SUBCLASS_SETUP(class_, name_) \ + { name_##_buffer, reinterpret_cast(&class_::name_) }, + +// Holds data used to initialize large number of atoms during startup. Use +// NS_STATIC_ATOM_SETUP to initialize these structs. They should never be +// accessed directly other than from nsAtomTable.cpp. struct nsStaticAtomSetup { const char16_t* const mString; nsAtom** const mAtom; }; -// Register an array of static atoms with the atom table +// Register an array of static atoms with the atom table. template void NS_RegisterStaticAtoms(const nsStaticAtomSetup (&aSetup)[N]) diff --git a/xpcom/io/nsDirectoryService.cpp b/xpcom/io/nsDirectoryService.cpp index 6a238cc0f876..5d6eef88a301 100644 --- a/xpcom/io/nsDirectoryService.cpp +++ b/xpcom/io/nsDirectoryService.cpp @@ -105,18 +105,19 @@ nsDirectoryService::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) return gService->QueryInterface(aIID, aResult); } -#define DIR_ATOM(name_, value_) nsAtom* nsDirectoryService::name_ = nullptr; +#define DIR_ATOM(name_, value_) NS_STATIC_ATOM_DEFN(nsDirectoryService, name_) #include "nsDirectoryServiceAtomList.h" #undef DIR_ATOM -#define DIR_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_) +#define DIR_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_, value_) #include "nsDirectoryServiceAtomList.h" #undef DIR_ATOM static const nsStaticAtomSetup sDirectoryServiceAtomSetup[] = { -#define DIR_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(name_##_buffer, &nsDirectoryService::name_), -#include "nsDirectoryServiceAtomList.h" -#undef DIR_ATOM + #define DIR_ATOM(name_, value_) \ + NS_STATIC_ATOM_SETUP(nsDirectoryService, name_) + #include "nsDirectoryServiceAtomList.h" + #undef DIR_ATOM }; NS_IMETHODIMP diff --git a/xpcom/io/nsDirectoryService.h b/xpcom/io/nsDirectoryService.h index e121dc5fb496..74c9f964363c 100644 --- a/xpcom/io/nsDirectoryService.h +++ b/xpcom/io/nsDirectoryService.h @@ -11,6 +11,7 @@ #include "nsInterfaceHashtable.h" #include "nsIFile.h" #include "nsAtom.h" +#include "nsStaticAtom.h" #include "nsTArray.h" #include "mozilla/Attributes.h" #include "mozilla/StaticPtr.h" @@ -54,13 +55,9 @@ private: nsTArray> mProviders; public: - -#define DIR_ATOM(name_, value_) static nsAtom* name_; -#include "nsDirectoryServiceAtomList.h" -#undef DIR_ATOM - + #define DIR_ATOM(name_, value_) NS_STATIC_ATOM_DECL(name_) + #include "nsDirectoryServiceAtomList.h" + #undef DIR_ATOM }; - #endif -