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
This commit is contained in:
Nicholas Nethercote 2017-10-22 08:50:25 +11:00
parent ed06034e3c
commit 21e7dce1a2
17 changed files with 286 additions and 202 deletions

View File

@ -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()

View File

@ -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___ */

View File

@ -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

View File

@ -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.

View File

@ -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',
]

View File

@ -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()

View File

@ -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

View File

@ -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<CSSPseudoElementTypeBase>(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<CSSPseudoElementTypeBase>(Type::name_); \
Preferences::AddBoolVarCache(&sPseudoClassEnabled[idx], pref_); \
}
#include "nsCSSPseudoClassList.h"
#undef CSS_PSEUDO_CLASS
}
bool

View File

@ -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

View File

@ -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

View File

@ -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...

View File

@ -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[];

View File

@ -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

View File

@ -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);
}

View File

@ -7,31 +7,116 @@
#ifndef nsStaticAtom_h__
#define nsStaticAtom_h__
#include "nsAtom.h"
#include "nsStringBuffer.h"
#include <stdint.h>
#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<nsAtom**>(&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<uint32_t N>
void
NS_RegisterStaticAtoms(const nsStaticAtomSetup (&aSetup)[N])

View File

@ -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

View File

@ -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<nsCOMPtr<nsIDirectoryServiceProvider>> 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