import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1175810 (part 1) - Remove PL_DHashTableEnumerator() use from nsScriptNameSpaceManager. r=bz. (e9ab9ba0a)
- Bug 1176160 (part 1) - Remove simple uses of PL_DHashTableEnumerator() from rdf/. r=bsmedberg. (4c97b159f)
- Bug 1176160 (part 2) - Remove uses of PL_DHashTableEnumerator() involving VisitorClosure from rdf/. r=bsmedberg. (170ee22a9)
- Bug 1176160 (part 3) - Remove uses of PL_DHashTableEnumerator() from SweepForwardArcsEntries(). r=pike. (2442d92c5)
- Bug 1175810 (part 2) - Remove PL_DHashTableEnumerate() uses from nsJSNPRuntime. r=bz. (58d6b5fbe)
- Bug 1155836: Template on aComputeData in the DoGetStyle* helpers. r=dbaron f=bz (4f951a66b)
- Bug 1144885 - Treat font-size-adjust: none as separate from font-size-adjust: 0. r=jdaggett (e7327b7db)
- Bug 1144885 - Add reftests for font-size:0 and font-size-adjust:0. r=jdaggett (fb9d997c0)
- Bug 1144885 followup - Remove spec links from reference, which the CSS test suite validator treats as an error. (40f92e039)
- Bug 1147423 part 1 - [css-grid] Use a signed integer type for some line variables in preparation for negative implicit lines. r=dholbert (b810f12bf)
- Bug 1147423 part 2 - [css-grid] Clamp grid lines to the -10000 .. 10000 range. r=dholbert (001e1f0bd)
- Bug 1161325 - Make nsStyleVariables copy constructor behave more traditionally. r=dbaron (f612b94c1)
This commit is contained in:
2021-01-27 22:18:18 +08:00
parent dcf9e5848a
commit 38a2cf9203
35 changed files with 543 additions and 555 deletions
+8 -31
View File
@@ -2293,35 +2293,6 @@ Navigator::MayResolve(jsid aId)
return nameSpaceManager->LookupNavigatorName(name);
}
struct NavigatorNameEnumeratorClosure
{
NavigatorNameEnumeratorClosure(JSContext* aCx, JSObject* aWrapper,
nsTArray<nsString>& aNames)
: mCx(aCx),
mWrapper(aCx, aWrapper),
mNames(aNames)
{
}
JSContext* mCx;
JS::Rooted<JSObject*> mWrapper;
nsTArray<nsString>& mNames;
};
static PLDHashOperator
SaveNavigatorName(const nsAString& aName,
const nsGlobalNameStruct& aNameStruct,
void* aClosure)
{
NavigatorNameEnumeratorClosure* closure =
static_cast<NavigatorNameEnumeratorClosure*>(aClosure);
if (!aNameStruct.mConstructorEnabled ||
aNameStruct.mConstructorEnabled(closure->mCx, closure->mWrapper)) {
closure->mNames.AppendElement(aName);
}
return PL_DHASH_NEXT;
}
void
Navigator::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
ErrorResult& aRv)
@@ -2333,8 +2304,14 @@ Navigator::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
return;
}
NavigatorNameEnumeratorClosure closure(aCx, GetWrapper(), aNames);
nameSpaceManager->EnumerateNavigatorNames(SaveNavigatorName, &closure);
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
for (auto i = nameSpaceManager->NavigatorNameIter(); !i.Done(); i.Next()) {
const GlobalNameMapEntry* entry = i.Get();
if (!entry->mGlobalName.mConstructorEnabled ||
entry->mGlobalName.mConstructorEnabled(aCx, wrapper)) {
aNames.AppendElement(entry->mKey);
}
}
}
JSObject*
+10 -36
View File
@@ -4328,40 +4328,6 @@ nsGlobalWindow::MayResolve(jsid aId)
return name_struct;
}
struct GlobalNameEnumeratorClosure
{
GlobalNameEnumeratorClosure(JSContext* aCx, nsGlobalWindow* aWindow,
nsTArray<nsString>& aNames)
: mCx(aCx),
mWindow(aWindow),
mWrapper(aCx, aWindow->GetWrapper()),
mNames(aNames)
{
}
JSContext* mCx;
nsGlobalWindow* mWindow;
JS::Rooted<JSObject*> mWrapper;
nsTArray<nsString>& mNames;
};
static PLDHashOperator
EnumerateGlobalName(const nsAString& aName,
const nsGlobalNameStruct& aNameStruct,
void* aClosure)
{
GlobalNameEnumeratorClosure* closure =
static_cast<GlobalNameEnumeratorClosure*>(aClosure);
if (nsWindowSH::NameStructEnabled(closure->mCx, closure->mWindow, aName,
aNameStruct) &&
(!aNameStruct.mConstructorEnabled ||
aNameStruct.mConstructorEnabled(closure->mCx, closure->mWrapper))) {
closure->mNames.AppendElement(aName);
}
return PL_DHASH_NEXT;
}
void
nsGlobalWindow::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
ErrorResult& aRv)
@@ -4371,8 +4337,16 @@ nsGlobalWindow::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
nsScriptNameSpaceManager* nameSpaceManager = GetNameSpaceManager();
if (nameSpaceManager) {
GlobalNameEnumeratorClosure closure(aCx, this, aNames);
nameSpaceManager->EnumerateGlobalNames(EnumerateGlobalName, &closure);
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
for (auto i = nameSpaceManager->GlobalNameIter(); !i.Done(); i.Next()) {
const GlobalNameMapEntry* entry = i.Get();
if (nsWindowSH::NameStructEnabled(aCx, this, entry->mKey,
entry->mGlobalName) &&
(!entry->mGlobalName.mConstructorEnabled ||
entry->mGlobalName.mConstructorEnabled(aCx, wrapper))) {
aNames.AppendElement(entry->mKey);
}
}
}
}
-47
View File
@@ -35,23 +35,6 @@
using namespace mozilla;
// Our extended PLDHashEntryHdr
class GlobalNameMapEntry : public PLDHashEntryHdr
{
public:
// Our hash table ops don't care about the order of these members
nsString mKey;
nsGlobalNameStruct mGlobalName;
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) {
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - mGlobalName
return mKey.SizeOfExcludingThisMustBeUnshared(aMallocSizeOf);
}
};
static PLDHashNumber
GlobalNameHashHashKey(PLDHashTable *table, const void *key)
{
@@ -742,36 +725,6 @@ nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor(
}
}
struct NameClosure
{
nsScriptNameSpaceManager::NameEnumerator enumerator;
void* closure;
};
static PLDHashOperator
EnumerateName(PLDHashTable*, PLDHashEntryHdr *hdr, uint32_t, void* aClosure)
{
GlobalNameMapEntry *entry = static_cast<GlobalNameMapEntry *>(hdr);
NameClosure* closure = static_cast<NameClosure*>(aClosure);
return closure->enumerator(entry->mKey, entry->mGlobalName, closure->closure);
}
void
nsScriptNameSpaceManager::EnumerateGlobalNames(NameEnumerator aEnumerator,
void* aClosure)
{
NameClosure closure = { aEnumerator, aClosure };
PL_DHashTableEnumerate(&mGlobalNames, EnumerateName, &closure);
}
void
nsScriptNameSpaceManager::EnumerateNavigatorNames(NameEnumerator aEnumerator,
void* aClosure)
{
NameClosure closure = { aEnumerator, aClosure };
PL_DHashTableEnumerate(&mNavigatorNames, EnumerateName, &closure);
}
static size_t
SizeOfEntryExcludingThis(PLDHashEntryHdr *aHdr, MallocSizeOf aMallocSizeOf,
void *aArg)
+36 -4
View File
@@ -79,6 +79,21 @@ struct nsGlobalNameStruct
mozilla::dom::ConstructorEnabled* mConstructorEnabled;
};
class GlobalNameMapEntry : public PLDHashEntryHdr
{
public:
// Our hash table ops don't care about the order of these members.
nsString mKey;
nsGlobalNameStruct mGlobalName;
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - mGlobalName
return mKey.SizeOfExcludingThisMustBeUnshared(aMallocSizeOf);
}
};
class nsICategoryManager;
class nsScriptNameSpaceManager : public nsIObserver,
@@ -169,10 +184,27 @@ public:
const nsGlobalNameStruct& aGlobalNameStruct,
void* aClosure);
void EnumerateGlobalNames(NameEnumerator aEnumerator,
void* aClosure);
void EnumerateNavigatorNames(NameEnumerator aEnumerator,
void* aClosure);
class NameIterator : public PLDHashTable::Iterator
{
public:
typedef PLDHashTable::Iterator Base;
explicit NameIterator(PLDHashTable* aTable) : Base(aTable) {}
NameIterator(NameIterator&& aOther) : Base(mozilla::Move(aOther.mTable)) {}
const GlobalNameMapEntry* Get() const
{
return static_cast<const GlobalNameMapEntry*>(Base::Get());
}
private:
NameIterator() = delete;
NameIterator(const NameIterator&) = delete;
NameIterator& operator=(const NameIterator&) = delete;
NameIterator& operator=(const NameIterator&&) = delete;
};
NameIterator GlobalNameIter() { return NameIterator(&mGlobalNames); }
NameIterator NavigatorNameIter() { return NameIterator(&mNavigatorNames); }
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
+44 -66
View File
@@ -1947,66 +1947,6 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext* cx, NPObject* npobj)
return obj;
}
// Struct for passing an NPP and a JSContext to
// NPObjWrapperPluginDestroyedCallback
struct NppAndCx
{
NPP npp;
JSContext* cx;
};
static PLDHashOperator
NPObjWrapperPluginDestroyedCallback(PLDHashTable* table, PLDHashEntryHdr* hdr,
uint32_t number, void* arg)
{
NPObjWrapperHashEntry* entry = (NPObjWrapperHashEntry*)hdr;
NppAndCx* nppcx = reinterpret_cast<NppAndCx*>(arg);
if (entry->mNpp == nppcx->npp) {
// HACK: temporarily hide the hash we're enumerating so that invalidate()
// and deallocate() don't touch it.
PLDHashTable* tmp = static_cast<PLDHashTable*>(table);
sNPObjWrappers = nullptr;
NPObject* npobj = entry->mNPObj;
if (npobj->_class && npobj->_class->invalidate) {
npobj->_class->invalidate(npobj);
}
#ifdef NS_BUILD_REFCNT_LOGGING
{
int32_t refCnt = npobj->referenceCount;
while (refCnt) {
--refCnt;
NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
}
}
#endif
// Force deallocation of plugin objects since the plugin they came
// from is being torn down.
if (npobj->_class && npobj->_class->deallocate) {
npobj->_class->deallocate(npobj);
} else {
PR_Free(npobj);
}
::JS_SetPrivate(entry->mJSObj, nullptr);
sNPObjWrappers = tmp;
if (sDelayedReleases && sDelayedReleases->RemoveElement(npobj)) {
OnWrapperDestroyed();
}
return PL_DHASH_REMOVE;
}
return PL_DHASH_NEXT;
}
// static
void
nsJSNPRuntime::OnPluginDestroy(NPP npp)
@@ -2033,13 +1973,51 @@ nsJSNPRuntime::OnPluginDestroy(NPP npp)
sJSObjWrappersAccessible = true;
}
// Use the safe JSContext here as we're not always able to find the
// JSContext associated with the NPP any more.
AutoSafeJSContext cx;
if (sNPObjWrappers) {
NppAndCx nppcx = { npp, cx };
PL_DHashTableEnumerate(sNPObjWrappers,
NPObjWrapperPluginDestroyedCallback, &nppcx);
for (auto i = sNPObjWrappers->RemovingIter(); !i.Done(); i.Next()) {
auto entry = static_cast<NPObjWrapperHashEntry*>(i.Get());
if (entry->mNpp == npp) {
// HACK: temporarily hide the table we're enumerating so that
// invalidate() and deallocate() don't touch it.
PLDHashTable *tmp = sNPObjWrappers;
sNPObjWrappers = nullptr;
NPObject *npobj = entry->mNPObj;
if (npobj->_class && npobj->_class->invalidate) {
npobj->_class->invalidate(npobj);
}
#ifdef NS_BUILD_REFCNT_LOGGING
{
int32_t refCnt = npobj->referenceCount;
while (refCnt) {
--refCnt;
NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
}
}
#endif
// Force deallocation of plugin objects since the plugin they came
// from is being torn down.
if (npobj->_class && npobj->_class->deallocate) {
npobj->_class->deallocate(npobj);
} else {
PR_Free(npobj);
}
::JS_SetPrivate(entry->mJSObj, nullptr);
sNPObjWrappers = tmp;
if (sDelayedReleases && sDelayedReleases->RemoveElement(npobj)) {
OnWrapperDestroyed();
}
i.Remove();
}
}
}
}
+1 -1
View File
@@ -49,7 +49,7 @@ nsFont::Init()
{
systemFont = false;
smoothing = NS_FONT_SMOOTHING_AUTO;
sizeAdjust = 0.0;
sizeAdjust = -1.0f;
kerning = NS_FONT_KERNING_AUTO;
synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
+2 -2
View File
@@ -92,8 +92,8 @@ struct NS_GFX nsFont {
// The aspect-value (ie., the ratio actualsize:actualxheight) that any
// actual physical font created from this font structure must have when
// rendering or measuring a string. A value of 0 means no adjustment
// needs to be done.
// rendering or measuring a string. A value of -1.0 means no adjustment
// needs to be done; otherwise the value must be nonnegative.
float sizeAdjust;
// -- list of value tags for font-specific alternate features
+1 -1
View File
@@ -162,7 +162,7 @@ gfxDWriteFont::ComputeMetrics(AntialiasOption anAAOption)
mFontFace->GetMetrics(&fontMetrics);
}
if (mStyle.sizeAdjust != 0.0) {
if (mStyle.sizeAdjust >= 0.0) {
gfxFloat aspect = (gfxFloat)fontMetrics.xHeight /
fontMetrics.designUnitsPerEm;
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
+2 -1
View File
@@ -114,7 +114,8 @@ gfxFT2FontBase::GetHorizontalMetrics()
if (mHasMetrics)
return mMetrics;
if (MOZ_UNLIKELY(GetStyle()->size <= 0.0)) {
if (MOZ_UNLIKELY(GetStyle()->size <= 0.0) ||
MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0)) {
new(&mMetrics) gfxFont::Metrics(); // zero initialize
mSpaceGlyph = GetGlyph(' ');
} else {
+4 -3
View File
@@ -2201,6 +2201,7 @@ gfxFont::Measure(gfxTextRun *aTextRun,
((aBoundingBoxType == LOOSE_INK_EXTENTS &&
!needsGlyphExtents &&
!aTextRun->HasDetailedGlyphs()) ||
(MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0)) ||
(MOZ_UNLIKELY(GetStyle()->size == 0))) ? nullptr
: GetOrCreateGlyphExtents(aTextRun->GetAppUnitsPerDevUnit());
double x = 0;
@@ -3341,7 +3342,7 @@ gfxFont::SanitizeMetrics(gfxFont::Metrics *aMetrics, bool aIsBadUnderlineFont)
{
// Even if this font size is zero, this font is created with non-zero size.
// However, for layout and others, we should return the metrics of zero size font.
if (mStyle.size == 0.0) {
if (mStyle.size == 0.0 || mStyle.sizeAdjust == 0.0) {
memset(aMetrics, 0, sizeof(gfxFont::Metrics));
return;
}
@@ -3656,7 +3657,7 @@ gfxFontStyle::ParseFontLanguageOverride(const nsString& aLangTag)
gfxFontStyle::gfxFontStyle() :
language(nsGkAtoms::x_western),
size(DEFAULT_PIXEL_FONT_SIZE), sizeAdjust(0.0f), baselineOffset(0.0f),
size(DEFAULT_PIXEL_FONT_SIZE), sizeAdjust(-1.0f), baselineOffset(0.0f),
languageOverride(NO_FONT_LANGUAGE_OVERRIDE),
weight(NS_FONT_WEIGHT_NORMAL), stretch(NS_FONT_STRETCH_NORMAL),
systemFont(true), printerFont(false), useGrayscaleAntialiasing(false),
@@ -3701,7 +3702,7 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
if (size >= FONT_MAX_SIZE) {
size = FONT_MAX_SIZE;
sizeAdjust = 0.0;
sizeAdjust = -1.0f;
} else if (size < 0.0) {
NS_WARNING("negative font size");
size = 0.0;
+7 -5
View File
@@ -105,8 +105,8 @@ struct gfxFontStyle {
// The aspect-value (ie., the ratio actualsize:actualxheight) that any
// actual physical font created from this font structure must have when
// rendering or measuring a string. A value of 0 means no adjustment
// needs to be done.
// rendering or measuring a string. A value of -1.0 means no adjustment
// needs to be done; otherwise the value must be nonnegative.
float sizeAdjust;
// baseline offset, used when simulating sub/superscript glyphs
@@ -164,9 +164,9 @@ struct gfxFontStyle {
uint8_t variantSubSuper;
// Return the final adjusted font size for the given aspect ratio.
// Not meant to be called when sizeAdjust = 0.
// Not meant to be called when sizeAdjust = -1.0.
gfxFloat GetAdjustedSize(gfxFloat aspect) const {
NS_ASSERTION(sizeAdjust != 0.0, "Not meant to be called when sizeAdjust = 0");
NS_ASSERTION(sizeAdjust >= 0.0, "Not meant to be called when sizeAdjust = -1.0");
gfxFloat adjustedSize = std::max(NS_round(size*(sizeAdjust/aspect)), 1.0);
return std::min(adjustedSize, FONT_MAX_SIZE);
}
@@ -1389,7 +1389,9 @@ public:
}
virtual gfxFloat GetAdjustedSize() const {
return mAdjustedSize > 0.0 ? mAdjustedSize : mStyle.size;
return mAdjustedSize > 0.0
? mAdjustedSize
: (mStyle.sizeAdjust == 0.0 ? 0.0 : mStyle.size);
}
float FUnitsToDevUnitsFactor() const {
+3 -1
View File
@@ -194,7 +194,7 @@ gfxGDIFont::Initialize()
if (mAdjustedSize == 0.0) {
mAdjustedSize = mStyle.size;
if (mStyle.sizeAdjust != 0.0 && mAdjustedSize > 0.0) {
if (mStyle.sizeAdjust > 0.0 && mAdjustedSize > 0.0) {
// to implement font-size-adjust, we first create the "unadjusted" font
FillLogFont(logFont, mAdjustedSize,
wantFakeItalic && !useCairoFakeItalic);
@@ -213,6 +213,8 @@ gfxGDIFont::Initialize()
mFont = nullptr;
delete mMetrics;
mMetrics = nullptr;
} else if (mStyle.sizeAdjust == 0.0) {
mAdjustedSize = 0.0;
}
}
+1 -1
View File
@@ -254,7 +254,7 @@ gfxMacFont::InitMetrics()
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
}
if (mStyle.sizeAdjust != 0.0 && mStyle.size > 0.0 &&
if (mStyle.sizeAdjust > 0.0 && mStyle.size > 0.0 &&
mMetrics.xHeight > 0.0) {
// apply font-size-adjust, and recalculate metrics
gfxFloat aspect = mMetrics.xHeight / mStyle.size;
+1 -1
View File
@@ -1854,7 +1854,7 @@ gfxPangoFontGroup::GetBaseFontSet()
MakeFontSet(mPangoLanguage, mSizeAdjustFactor, &pattern);
double size = GetPixelSize(pattern);
if (size != 0.0 && mStyle.sizeAdjust != 0.0) {
if (size != 0.0 && mStyle.sizeAdjust > 0.0) {
gfxFcFont *font = fontSet->GetFontAt(0, GetStyle());
if (font) {
const gfxFont::Metrics& metrics =
+8 -4
View File
@@ -1353,7 +1353,8 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
for (i = 0; i < runCount; ++i) {
const GlyphRun& run = mGlyphRuns[i];
gfxFont *font = run.mFont;
if (MOZ_UNLIKELY(font->GetStyle()->size == 0)) {
if (MOZ_UNLIKELY(font->GetStyle()->size == 0) ||
MOZ_UNLIKELY(font->GetStyle()->sizeAdjust == 0.0f)) {
continue;
}
@@ -2010,7 +2011,8 @@ gfxFontGroup::MakeSpaceTextRun(const Parameters *aParams, uint32_t aFlags)
}
gfxFont *font = GetFirstValidFont();
if (MOZ_UNLIKELY(GetStyle()->size == 0)) {
if (MOZ_UNLIKELY(GetStyle()->size == 0) ||
MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0f)) {
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
// them, and always create at least size 1 fonts, i.e. they still
// render something for size 0 fonts.
@@ -2109,7 +2111,8 @@ gfxFontGroup::MakeTextRun(const uint8_t *aString, uint32_t aLength,
aFlags |= TEXT_IS_8BIT;
if (GetStyle()->size == 0) {
if (MOZ_UNLIKELY(GetStyle()->size == 0) ||
MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0f)) {
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
// them, and always create at least size 1 fonts, i.e. they still
// render something for size 0 fonts.
@@ -2140,7 +2143,8 @@ gfxFontGroup::MakeTextRun(const char16_t *aString, uint32_t aLength,
if (aLength == 1 && aString[0] == ' ') {
return MakeSpaceTextRun(aParams, aFlags);
}
if (GetStyle()->size == 0) {
if (MOZ_UNLIKELY(GetStyle()->size == 0) ||
MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0f)) {
return MakeBlankTextRun(aLength, aParams, aFlags);
}
+31 -18
View File
@@ -333,7 +333,8 @@ nsGridContainerFrame::AddImplicitNamedAreas(
// (x-start) 0 (x-start) 0 (x-end)
// (x-end) 0 (x-start) 0 (x-end)
// (x-start) 0 (x-end) 0 (x-start) 0 (x-end)
const uint32_t len = aLineNameLists.Length();
const uint32_t len =
std::min(aLineNameLists.Length(), size_t(nsStyleGridLine::kMaxLine));
nsTHashtable<nsStringHashKey> currentStarts;
ImplicitNamedAreas* areas = GetImplicitNamedAreas();
for (uint32_t i = 0; i < len; ++i) {
@@ -374,7 +375,7 @@ nsGridContainerFrame::InitImplicitNamedAreas(const nsStylePosition* aStyle)
}
}
uint32_t
int32_t
nsGridContainerFrame::ResolveLine(
const nsStyleGridLine& aLine,
int32_t aNth,
@@ -387,7 +388,7 @@ nsGridContainerFrame::ResolveLine(
const nsStylePosition* aStyle)
{
MOZ_ASSERT(!aLine.IsAuto());
uint32_t line = 0;
int32_t line = 0;
if (aLine.mLineName.IsEmpty()) {
MOZ_ASSERT(aNth != 0, "css-grid 9.2: <integer> must not be zero.");
line = std::max(int32_t(aFromIndex) + aNth, 1);
@@ -460,7 +461,7 @@ nsGridContainerFrame::ResolveLine(
// <custom-ident> (without <integer> or 'span') which wasn't found.
MOZ_ASSERT(line != 0 || (!aLine.mHasSpan && aLine.mInteger == 0),
"Given a <integer> or 'span' the result should never be auto");
return line;
return clamped(line, nsStyleGridLine::kMinLine, nsStyleGridLine::kMaxLine);
}
nsGridContainerFrame::LinePair
@@ -501,7 +502,7 @@ nsGridContainerFrame::ResolveLineRangeHelper(
return LinePair(start, end);
}
uint32_t start = 0;
int32_t start = 0;
if (!aStart.IsAuto()) {
start = ResolveLine(aStart, aStart.mInteger, 0, aLineNameList, aAreaStart,
aAreaEnd, aExplicitGridEnd, eLineRangeSideStart,
@@ -530,7 +531,7 @@ nsGridContainerFrame::ResolveLineRangeHelper(
end = 1; // XXX subgrid explicit size instead of 1?
} else if (start == 0) {
// auto (or not found <custom-ident>) / definite line
start = std::max(1U, end - 1);
start = std::max(1, end - 1);
}
return LinePair(start, end);
}
@@ -549,8 +550,16 @@ nsGridContainerFrame::ResolveLineRange(
aAreaEnd, aExplicitGridEnd, aStyle);
MOZ_ASSERT(r.second != 0);
// http://dev.w3.org/csswg/css-grid/#grid-placement-errors
if (r.second <= r.first) {
if (r.first == 0) {
// r.second is a span, clamp it to kMaxLine - 1 so that the returned
// range has a HypotheticalEnd <= kMaxLine.
// http://dev.w3.org/csswg/css-grid/#overlarge-grids
r.second = std::min(r.second, nsStyleGridLine::kMaxLine - 1);
} else if (r.second <= r.first) {
// http://dev.w3.org/csswg/css-grid/#grid-placement-errors
if (MOZ_UNLIKELY(r.first == nsStyleGridLine::kMaxLine)) {
r.first = nsStyleGridLine::kMaxLine - 1;
}
r.second = r.first + 1;
}
return LineRange(r.first, r.second);
@@ -587,25 +596,25 @@ nsGridContainerFrame::ResolveAbsPosLineRange(
if (aEnd.IsAuto()) {
return LineRange(0, 0);
}
uint32_t end = ResolveLine(aEnd, aEnd.mInteger, 0, aLineNameList, aAreaStart,
aAreaEnd, aExplicitGridEnd, eLineRangeSideEnd,
aStyle);
int32_t end = ResolveLine(aEnd, aEnd.mInteger, 0, aLineNameList, aAreaStart,
aAreaEnd, aExplicitGridEnd, eLineRangeSideEnd,
aStyle);
MOZ_ASSERT(end != 0, "resolving non-auto line shouldn't result in auto");
if (aEnd.mHasSpan) {
++end;
}
return LineRange(0, clamped(end, 1U, aGridEnd));
return LineRange(0, clamped(end, 1, int32_t(aGridEnd)));
}
if (aEnd.IsAuto()) {
uint32_t start =
int32_t start =
ResolveLine(aStart, aStart.mInteger, 0, aLineNameList, aAreaStart,
aAreaEnd, aExplicitGridEnd, eLineRangeSideStart, aStyle);
MOZ_ASSERT(start != 0, "resolving non-auto line shouldn't result in auto");
if (aStart.mHasSpan) {
start = std::max(int32_t(aGridEnd) - int32_t(start), 1);
start = std::max(int32_t(aGridEnd) - start, 1);
}
return LineRange(clamped(start, 1U, aGridEnd), 0);
return LineRange(clamped(start, 1, int32_t(aGridEnd)), 0);
}
LineRange r = ResolveLineRange(aStart, aEnd, aLineNameList, aAreaStart,
@@ -613,8 +622,8 @@ nsGridContainerFrame::ResolveAbsPosLineRange(
MOZ_ASSERT(!r.IsAuto(), "resolving definite lines shouldn't result in auto");
// Clamp definite lines to be within the implicit grid.
// Note that this implies mStart may be equal to mEnd.
r.mStart = clamped(r.mStart, 1U, aGridEnd);
r.mEnd = clamped(r.mEnd, 1U, aGridEnd);
r.mStart = clamped(r.mStart, 1, int32_t(aGridEnd));
r.mEnd = clamped(r.mEnd, 1, int32_t(aGridEnd));
MOZ_ASSERT(r.mStart <= r.mEnd);
return r;
}
@@ -788,6 +797,10 @@ nsGridContainerFrame::InitializeGridBounds(const nsStylePosition* aStyle)
auto areas = aStyle->mGridTemplateAreas.get();
mExplicitGridColEnd = std::max(colEnd, areas ? areas->mNColumns + 1 : 1);
mExplicitGridRowEnd = std::max(rowEnd, areas ? areas->NRows() + 1 : 1);
mExplicitGridColEnd =
std::min(mExplicitGridColEnd, uint32_t(nsStyleGridLine::kMaxLine));
mExplicitGridRowEnd =
std::min(mExplicitGridRowEnd, uint32_t(nsStyleGridLine::kMaxLine));
mGridColEnd = mExplicitGridColEnd;
mGridRowEnd = mExplicitGridRowEnd;
}
@@ -875,7 +888,7 @@ nsGridContainerFrame::PlaceGridItems(GridItemCSSOrderIterator& aIter,
if (minor.IsDefinite()) {
// Items with 'auto' in the major dimension only.
if (isSparse) {
if (minor.mStart < cursorMinor) {
if (minor.mStart < int32_t(cursorMinor)) {
++cursorMajor;
}
cursorMinor = minor.mStart;
+15 -15
View File
@@ -83,7 +83,7 @@ protected:
* i.e. the invariant is slightly relaxed compared to normal flow items.
*/
struct LineRange {
LineRange(uint32_t aStart, uint32_t aEnd)
LineRange(int32_t aStart, int32_t aEnd)
: mStart(aStart), mEnd(aEnd) {}
bool IsAuto() const { return mStart == 0; }
bool IsDefinite() const { return mStart != 0; }
@@ -92,11 +92,11 @@ protected:
* Resolve this auto range to start at aStart, making it definite.
* Precondition: this range IsAuto()
*/
void ResolveAutoPosition(uint32_t aStart)
void ResolveAutoPosition(int32_t aStart)
{
MOZ_ASSERT(IsAuto(), "Why call me?");
MOZ_ASSERT(aStart > 0, "expected a 1-based line number");
MOZ_ASSERT(Extent() == mEnd, "'auto' representation changed?");
MOZ_ASSERT(int32_t(Extent()) == mEnd, "'auto' representation changed?");
mStart = aStart;
mEnd += aStart;
}
@@ -121,8 +121,8 @@ protected:
nscoord aGridOrigin,
nscoord* aPos, nscoord* aLength) const;
uint32_t mStart; // the start line, or zero for 'auto'
uint32_t mEnd; // the end line, or the span length for 'auto'
int32_t mStart; // the start line, or zero for 'auto'
int32_t mEnd; // the end line, or the span length for 'auto'
};
/**
@@ -181,15 +181,15 @@ protected:
* @return a definite line number, or zero in case aLine is a <custom-ident>
* that can't be found.
*/
uint32_t ResolveLine(const nsStyleGridLine& aLine,
int32_t aNth,
uint32_t aFromIndex,
const nsTArray<nsTArray<nsString>>& aLineNameList,
uint32_t GridNamedArea::* aAreaStart,
uint32_t GridNamedArea::* aAreaEnd,
uint32_t aExplicitGridEnd,
LineRangeSide aEdge,
const nsStylePosition* aStyle);
int32_t ResolveLine(const nsStyleGridLine& aLine,
int32_t aNth,
uint32_t aFromIndex,
const nsTArray<nsTArray<nsString>>& aLineNameList,
uint32_t GridNamedArea::* aAreaStart,
uint32_t GridNamedArea::* aAreaEnd,
uint32_t aExplicitGridEnd,
LineRangeSide aEdge,
const nsStylePosition* aStyle);
/**
* Return a LineRange based on the given style data. Non-auto lines
* are resolved to a definite line number per:
@@ -342,7 +342,7 @@ protected:
* @see ResolveLineRange
* @return a pair (start,end) of lines
*/
typedef std::pair<uint32_t, uint32_t> LinePair;
typedef std::pair<int32_t, int32_t> LinePair;
LinePair ResolveLineRangeHelper(const nsStyleGridLine& aStart,
const nsStyleGridLine& aEnd,
const nsTArray<nsTArray<nsString>>& aLineNameList,
@@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<title>CSS Test: font-size-adjust: 0</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-size-adjust-prop">
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins">
<link rel="match" href="font-size-zero-2-ref.html">
<meta name="flags" content="">
<style>
/* spec ambiguous whether font-size-adjust influences line-height: normal */
body { line-height: 1.2 }
p { margin: 1em 0 }
p.zero { font-size-adjust: 0 }
</style>
<p>before</p>
<p class="zero">zero</p>
<p>after</p>
@@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<title>CSS Test: font-size-adjust: 0</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-size-adjust-prop">
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins">
<link rel="match" href="font-size-zero-2-ref.html">
<meta name="flags" content="">
<style>
/* spec ambiguous whether font-size-adjust influences line-height: normal */
body { line-height: 1.2 }
span { line-height: 0 }
p { margin: 1em 0 }
span.zero { font-size-adjust: 0 }
</style>
<p>before</p>
<p><span class="zero">zero</span></p>
<p>after</p>
@@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<title>CSS Test Reference</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<meta name="flags" content="">
<style>
/* spec ambiguous whether font-size-adjust influences line-height: normal */
body { line-height: 1.2 }
</style>
<p>before</p>
<p>zero</p>
<p>after</p>
@@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<title>CSS Test Reference</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="mismatch" href="font-size-zero-1-notref.html">
<meta name="flags" content="">
<style>
/* spec ambiguous whether font-size-adjust influences line-height: normal */
body { line-height: 1.2 }
p { margin: 1em 0 }
p.first { margin-bottom: 2em }
</style>
<p class="first">before</p>
<p>after</p>
@@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<title>CSS Test: font-size: 0</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-size-prop">
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins">
<link rel="match" href="font-size-zero-1-ref.html">
<meta name="flags" content="">
<style>
/* spec ambiguous whether font-size-adjust influences line-height: normal */
body { line-height: 1.2 }
p { margin: 1em 0 }
p.zero { font-size: 0 }
</style>
<p>before</p>
<p class="zero">zero</p>
<p>after</p>
@@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<title>CSS Test Reference</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<meta name="flags" content="">
<style>
/* spec ambiguous whether font-size-adjust influences line-height: normal */
body { line-height: 1.2 }
</style>
<p>before</p>
<p>&nbsp;</p>
<p>after</p>
@@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<title>CSS Test: font-size: 0</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-size-prop">
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins">
<link rel="match" href="font-size-zero-2-ref.html">
<meta name="flags" content="">
<style>
/* spec ambiguous whether font-size-adjust influences line-height: normal */
body { line-height: 1.2 }
p { margin: 1em 0 }
span.zero { font-size: 0 }
</style>
<p>before</p>
<p><span class="zero">zero</span></p>
<p>after</p>
@@ -0,0 +1,5 @@
== font-size-zero-1.html font-size-zero-1-ref.html
!= font-size-zero-1-ref.html font-size-zero-1-notref.html
== font-size-zero-2.html font-size-zero-2-ref.html
== font-size-adjust-zero-1.html font-size-zero-2-ref.html
== font-size-adjust-zero-2.html font-size-zero-2-ref.html
@@ -23,7 +23,7 @@ include conditional3/reftest.list
include flexbox/reftest.list
# Fonts Level 3
# include fonts3/reftest.list
include fonts3/reftest.list
# Image Values and Replaced Content Level 3
include images3/reftest.list
+2 -2
View File
@@ -3448,8 +3448,8 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
aComputedValue.SetFloatValue(*static_cast<const float*>(
StyleDataAtOffset(styleStruct, ssOffset)));
if (aProperty == eCSSProperty_font_size_adjust &&
aComputedValue.GetFloatValue() == 0.0f) {
// In nsStyleFont, we set mFont.sizeAdjust to 0 to represent
aComputedValue.GetFloatValue() == -1.0f) {
// In nsStyleFont, we set mFont.sizeAdjust to -1.0 to represent
// font-size-adjust: none. Here, we have to treat this as a keyword
// instead of a float value, to make sure we don't end up doing
// interpolation with it.
+1 -1
View File
@@ -1435,7 +1435,7 @@ nsComputedDOMStyle::DoGetFontSizeAdjust()
const nsStyleFont *font = StyleFont();
if (font->mFont.sizeAdjust) {
if (font->mFont.sizeAdjust >= 0.0f) {
val->SetNumber(font->mFont.sizeAdjust);
} else {
val->SetIdent(eCSSKeyword_none);
+11 -32
View File
@@ -17,7 +17,7 @@
#include "mozilla/Likely.h"
#include "mozilla/LookAndFeel.h"
#include "nsDeviceContext.h"
#include "nsAlgorithm.h" // for clamped()
#include "nsRuleNode.h"
#include "nscore.h"
#include "nsIWidget.h"
@@ -2612,7 +2612,12 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
parentdata_ = maybeFakeParentData.ptr(); \
} \
} \
if (aStartStruct) \
if (eStyleStruct_##type_ == eStyleStruct_Variables) \
/* no need to copy construct an nsStyleVariables, as we will copy */ \
/* inherited variables (and set canStoreInRuleTree to false) in */ \
/* ComputeVariablesData */ \
data_ = new (mPresContext) nsStyle##type_ ctorargs_; \
else if (aStartStruct) \
/* We only need to compute the delta between this computed data and */ \
/* our computed data. */ \
data_ = new (mPresContext) \
@@ -3795,7 +3800,7 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
aFont->mFont.sizeAdjust = systemFont.sizeAdjust;
} else
SetFactor(*sizeAdjustValue, aFont->mFont.sizeAdjust,
aCanStoreInRuleTree, aParentFont->mFont.sizeAdjust, 0.0f,
aCanStoreInRuleTree, aParentFont->mFont.sizeAdjust, -1.0f,
SETFCT_NONE | SETFCT_UNSET_INHERIT);
}
@@ -7284,7 +7289,9 @@ SetGridLine(const nsCSSValue& aValue,
if (item->mValue.GetUnit() == eCSSUnit_Enumerated) {
aResult.mHasSpan = true;
} else if (item->mValue.GetUnit() == eCSSUnit_Integer) {
aResult.mInteger = item->mValue.GetIntValue();
aResult.mInteger = clamped(item->mValue.GetIntValue(),
nsStyleGridLine::kMinLine,
nsStyleGridLine::kMaxLine);
} else if (item->mValue.GetUnit() == eCSSUnit_Ident) {
item->mValue.GetStringValue(aResult.mLineName);
} else {
@@ -9316,34 +9323,6 @@ nsRuleNode::GetStyleData(nsStyleStructID aSID,
return data;
}
// See comments above in GetStyleData for an explanation of what the
// code below does.
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_* \
nsRuleNode::GetStyle##name_(nsStyleContext* aContext, bool aComputeData) \
{ \
NS_ASSERTION(IsUsedDirectly(), \
"if we ever call this on rule nodes that aren't used " \
"directly, we should adjust handling of mDependentBits " \
"in some way."); \
\
const nsStyle##name_ *data; \
data = mStyleData.GetStyle##name_(); \
if (MOZ_LIKELY(data != nullptr)) \
return data; \
\
if (MOZ_UNLIKELY(!aComputeData)) \
return nullptr; \
\
data = static_cast<const nsStyle##name_ *> \
(WalkRuleTree(eStyleStruct_##name_, aContext)); \
\
MOZ_ASSERT(data, "should have aborted on out-of-memory"); \
return data; \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
void
nsRuleNode::Mark()
{
+26 -2
View File
@@ -715,9 +715,33 @@ public:
nsStyleContext* aContext,
bool aComputeData);
// See comments in GetStyleData for an explanation of what the
// code below does.
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_* GetStyle##name_(nsStyleContext* aContext, \
bool aComputeData);
template<bool aComputeData> \
const nsStyle##name_* \
GetStyle##name_(nsStyleContext* aContext) \
{ \
NS_ASSERTION(IsUsedDirectly(), \
"if we ever call this on rule nodes that aren't used " \
"directly, we should adjust handling of mDependentBits " \
"in some way."); \
\
const nsStyle##name_ *data; \
data = mStyleData.GetStyle##name_(); \
if (MOZ_LIKELY(data != nullptr)) \
return data; \
\
if (!aComputeData) \
return nullptr; \
\
data = static_cast<const nsStyle##name_ *> \
(WalkRuleTree(eStyleStruct_##name_, aContext)); \
\
MOZ_ASSERT(data, "should have aborted on out-of-memory"); \
return data; \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
+15 -12
View File
@@ -311,7 +311,7 @@ public:
*/
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * Style##name_() { \
return DoGetStyle##name_(true); \
return DoGetStyle##name_<true>(); \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@@ -325,7 +325,7 @@ public:
*/
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * PeekStyle##name_() { \
return DoGetStyle##name_(false); \
return DoGetStyle##name_<false>(); \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@@ -490,7 +490,8 @@ private:
// Helper functions for GetStyle* and PeekStyle*
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
const nsStyle##name_ * DoGetStyle##name_(bool aComputeData) { \
template<bool aComputeData> \
const nsStyle##name_ * DoGetStyle##name_() { \
const nsStyle##name_ * cachedData = \
static_cast<nsStyle##name_*>( \
mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]); \
@@ -498,19 +499,21 @@ private:
return cachedData; \
/* Have the rulenode deal */ \
AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \
return mRuleNode->GetStyle##name_(this, aComputeData); \
return mRuleNode->GetStyle##name_<aComputeData>(this); \
}
#define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
const nsStyle##name_ * DoGetStyle##name_(bool aComputeData) { \
const nsStyle##name_ * cachedData = mCachedResetData \
? static_cast<nsStyle##name_*>( \
mCachedResetData->mStyleStructs[eStyleStruct_##name_]) \
: nullptr; \
if (cachedData) /* Have it cached already, yay */ \
return cachedData; \
template<bool aComputeData> \
const nsStyle##name_ * DoGetStyle##name_() { \
if (mCachedResetData) { \
const nsStyle##name_ * cachedData = \
static_cast<nsStyle##name_*>( \
mCachedResetData->mStyleStructs[eStyleStruct_##name_]); \
if (cachedData) /* Have it cached already, yay */ \
return cachedData; \
} \
/* Have the rulenode deal */ \
AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \
return mRuleNode->GetStyle##name_(this, aComputeData); \
return mRuleNode->GetStyle##name_<aComputeData>(this); \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_RESET
+6
View File
@@ -36,6 +36,11 @@ static_assert((((1 << nsStyleStructID_Length) - 1) &
~(NS_STYLE_INHERIT_MASK)) == 0,
"Not enough bits in NS_STYLE_INHERIT_MASK");
// These are the limits that we choose to clamp grid line numbers to.
// http://dev.w3.org/csswg/css-grid/#overlarge-grids
const int32_t nsStyleGridLine::kMinLine = -10000;
const int32_t nsStyleGridLine::kMaxLine = 10000;
inline bool IsFixedUnit(const nsStyleCoord& aCoord, bool aEnumOK)
{
return aCoord.ConvertsToLength() ||
@@ -3669,6 +3674,7 @@ nsStyleVariables::nsStyleVariables()
nsStyleVariables::nsStyleVariables(const nsStyleVariables& aSource)
{
MOZ_COUNT_CTOR(nsStyleVariables);
mVariables = aSource.mVariables;
}
nsStyleVariables::~nsStyleVariables(void)
+5
View File
@@ -1270,10 +1270,15 @@ struct nsStyleGridTemplate {
struct nsStyleGridLine {
// http://dev.w3.org/csswg/css-grid/#typedef-grid-line
// XXXmats we could optimize memory size here
bool mHasSpan;
int32_t mInteger; // 0 means not provided
nsString mLineName; // Empty string means not provided.
// mInteger is clamped to this range:
static const int32_t kMinLine;
static const int32_t kMaxLine;
nsStyleGridLine()
: mHasSpan(false)
, mInteger(0)
+2 -2
View File
@@ -2563,8 +2563,8 @@ var gCSSProperties = {
inherited: true,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "0.3", "0.5", "0.7" ],
invalid_values: []
other_values: [ "0.3", "0.5", "0.7", "0.0", "0", "3" ],
invalid_values: [ "-0.3", "-1" ]
},
"font-stretch": {
domProp: "fontStretch",
+176 -266
View File
@@ -79,10 +79,6 @@
class Assertion
{
public:
static PLDHashOperator
DeletePropertyHashEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg);
Assertion(nsIRDFResource* aSource, // normal assertion
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
@@ -192,8 +188,18 @@ Assertion::Assertion(nsIRDFResource* aSource,
Assertion::~Assertion()
{
if (mHashEntry && u.hash.mPropertyHash) {
PL_DHashTableEnumerate(u.hash.mPropertyHash, DeletePropertyHashEntry,
nullptr);
for (auto i = u.hash.mPropertyHash->Iter(); !i.Done(); i.Next()) {
auto entry = static_cast<Entry*>(i.Get());
Assertion* as = entry->mAssertions;
while (as) {
Assertion* doomed = as;
as = as->mNext;
// Unlink, and release the datasource's reference.
doomed->mNext = doomed->u.as.mInvNext = nullptr;
doomed->Release();
}
}
delete u.hash.mPropertyHash;
u.hash.mPropertyHash = nullptr;
}
@@ -212,26 +218,6 @@ Assertion::~Assertion()
}
}
PLDHashOperator
Assertion::DeletePropertyHashEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg)
{
Entry* entry = static_cast<Entry*>(aHdr);
Assertion* as = entry->mAssertions;
while (as) {
Assertion* doomed = as;
as = as->mNext;
// Unlink, and release the datasource's reference.
doomed->mNext = doomed->u.as.mInvNext = nullptr;
doomed->Release();
}
return PL_DHASH_NEXT;
}
////////////////////////////////////////////////////////////////////////
// InMemoryDataSource
class InMemoryArcsEnumeratorImpl;
@@ -260,14 +246,6 @@ protected:
// during mReadCount == 0
uint32_t mReadCount;
static PLDHashOperator
DeleteForwardArcsEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg);
static PLDHashOperator
ResourceEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg);
friend class InMemoryArcsEnumeratorImpl;
friend class InMemoryAssertionEnumeratorImpl;
friend class InMemoryResourceEnumeratorImpl; // b/c it needs to enumerate mForwardArcs
@@ -310,9 +288,13 @@ public:
NS_DECL_RDFIDATASOURCE
protected:
static PLDHashOperator
SweepForwardArcsEntries(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg);
struct SweepInfo {
Assertion* mUnassertList;
PLDHashTable* mReverseArcs;
};
static void
SweepForwardArcsEntries(PLDHashTable* aTable, SweepInfo* aArg);
public:
// Implementation methods
@@ -561,10 +543,6 @@ private:
Assertion* mAssertion;
nsCOMPtr<nsISupportsArray> mHashArcs;
static PLDHashOperator
ArcEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg);
virtual ~InMemoryArcsEnumeratorImpl();
public:
@@ -580,19 +558,6 @@ public:
};
PLDHashOperator
InMemoryArcsEnumeratorImpl::ArcEnumerator(PLDHashTable* aTable,
PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg)
{
Entry* entry = static_cast<Entry*>(aHdr);
nsISupportsArray* resources = static_cast<nsISupportsArray*>(aArg);
resources->AppendElement(entry->mNode);
return PL_DHASH_NEXT;
}
InMemoryArcsEnumeratorImpl::InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource,
nsIRDFResource* aSource,
nsIRDFNode* aTarget)
@@ -613,8 +578,13 @@ InMemoryArcsEnumeratorImpl::InMemoryArcsEnumeratorImpl(InMemoryDataSource* aData
// its our magical HASH_ENTRY forward hash for assertions
nsresult rv = NS_NewISupportsArray(getter_AddRefs(mHashArcs));
if (NS_SUCCEEDED(rv)) {
PL_DHashTableEnumerate(mAssertion->u.hash.mPropertyHash,
ArcEnumerator, mHashArcs.get());
nsISupportsArray* resources = mHashArcs.get();
for (auto i = mAssertion->u.hash.mPropertyHash->Iter();
!i.Done();
i.Next()) {
auto entry = static_cast<Entry*>(i.Get());
resources->AppendElement(entry->mNode);
}
}
mAssertion = nullptr;
}
@@ -790,7 +760,18 @@ InMemoryDataSource::~InMemoryDataSource()
// associated with this data source. We only need to do this
// for the forward arcs, because the reverse arcs table
// indexes the exact same set of resources.
PL_DHashTableEnumerate(&mForwardArcs, DeleteForwardArcsEntry, nullptr);
for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<Entry*>(iter.Get());
Assertion* as = entry->mAssertions;
while (as) {
Assertion* doomed = as;
as = as->mNext;
// Unlink, and release the datasource's reference.
doomed->mNext = doomed->u.as.mInvNext = nullptr;
doomed->Release();
}
}
}
PR_LOG(gLog, PR_LOG_NOTICE,
@@ -799,24 +780,6 @@ InMemoryDataSource::~InMemoryDataSource()
MOZ_COUNT_DTOR(InMemoryDataSource);
}
PLDHashOperator
InMemoryDataSource::DeleteForwardArcsEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg)
{
Entry* entry = static_cast<Entry*>(aHdr);
Assertion* as = entry->mAssertions;
while (as) {
Assertion* doomed = as;
as = as->mNext;
// Unlink, and release the datasource's reference.
doomed->mNext = doomed->u.as.mInvNext = nullptr;
doomed->Release();
}
return PL_DHASH_NEXT;
}
////////////////////////////////////////////////////////////////////////
@@ -1607,16 +1570,6 @@ InMemoryDataSource::ArcLabelsOut(nsIRDFResource* aSource, nsISimpleEnumerator**
return NS_OK;
}
PLDHashOperator
InMemoryDataSource::ResourceEnumerator(PLDHashTable* aTable,
PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg)
{
Entry* entry = static_cast<Entry*>(aHdr);
static_cast<nsCOMArray<nsIRDFNode>*>(aArg)->AppendObject(entry->mNode);
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult)
@@ -1624,9 +1577,11 @@ InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult)
nsCOMArray<nsIRDFNode> nodes;
nodes.SetCapacity(mForwardArcs.EntryCount());
// Enumerate all of our entries into an nsCOMArray
PL_DHashTableEnumerate(&mForwardArcs, ResourceEnumerator, &nodes);
// Get all of our entries into an nsCOMArray
for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<Entry*>(iter.Get());
nodes.AppendObject(entry->mNode);
}
return NS_NewArrayEnumerator(aResult, nodes);
}
@@ -1813,19 +1768,13 @@ InMemoryDataSource::Mark(nsIRDFResource* aSource,
return NS_OK;
}
struct SweepInfo {
Assertion* mUnassertList;
PLDHashTable* mReverseArcs;
};
NS_IMETHODIMP
InMemoryDataSource::Sweep()
{
SweepInfo info = { nullptr, &mReverseArcs };
// Remove all the assertions, but don't notify anyone.
PL_DHashTableEnumerate(&mForwardArcs, SweepForwardArcsEntries, &info);
SweepForwardArcsEntries(&mForwardArcs, &info);
// Now do the notification.
Assertion* as = info.mUnassertList;
@@ -1853,126 +1802,92 @@ InMemoryDataSource::Sweep()
}
PLDHashOperator
void
InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable,
PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg)
SweepInfo* aInfo)
{
PLDHashOperator result = PL_DHASH_NEXT;
Entry* entry = static_cast<Entry*>(aHdr);
SweepInfo* info = static_cast<SweepInfo*>(aArg);
for (auto iter = aTable->RemovingIter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<Entry*>(iter.Get());
Assertion* as = entry->mAssertions;
if (as && (as->mHashEntry))
{
// Stuff in sub-hashes must be swept recursively (max depth: 1)
PL_DHashTableEnumerate(as->u.hash.mPropertyHash,
SweepForwardArcsEntries, info);
Assertion* as = entry->mAssertions;
if (as && (as->mHashEntry)) {
// Stuff in sub-hashes must be swept recursively (max depth: 1)
SweepForwardArcsEntries(as->u.hash.mPropertyHash, aInfo);
// If the sub-hash is now empty, clean it up.
if (!as->u.hash.mPropertyHash->EntryCount()) {
as->Release();
result = PL_DHASH_REMOVE;
// If the sub-hash is now empty, clean it up.
if (!as->u.hash.mPropertyHash->EntryCount()) {
as->Release();
iter.Remove();
}
continue;
}
return result;
}
Assertion* prev = nullptr;
while (as) {
if (as->IsMarked()) {
prev = as;
as->Unmark();
as = as->mNext;
}
else {
// remove from the list of assertions in the datasource
Assertion* next = as->mNext;
if (prev) {
prev->mNext = next;
Assertion* prev = nullptr;
while (as) {
if (as->IsMarked()) {
prev = as;
as->Unmark();
as = as->mNext;
}
else {
// it's the first one. update the hashtable entry.
entry->mAssertions = next;
}
// remove from the reverse arcs
PLDHashEntryHdr* hdr =
PL_DHashTableSearch(info->mReverseArcs, as->u.as.mTarget);
NS_ASSERTION(hdr, "no assertion in reverse arcs");
Entry* rentry = static_cast<Entry*>(hdr);
Assertion* ras = rentry->mAssertions;
Assertion* rprev = nullptr;
while (ras) {
if (ras == as) {
if (rprev) {
rprev->u.as.mInvNext = ras->u.as.mInvNext;
}
else {
// it's the first one. update the hashtable entry.
rentry->mAssertions = ras->u.as.mInvNext;
}
as->u.as.mInvNext = nullptr; // for my sanity.
break;
// remove from the list of assertions in the datasource
Assertion* next = as->mNext;
if (prev) {
prev->mNext = next;
}
rprev = ras;
ras = ras->u.as.mInvNext;
else {
// it's the first one. update the hashtable entry.
entry->mAssertions = next;
}
// remove from the reverse arcs
PLDHashEntryHdr* hdr =
PL_DHashTableSearch(aInfo->mReverseArcs, as->u.as.mTarget);
NS_ASSERTION(hdr, "no assertion in reverse arcs");
Entry* rentry = static_cast<Entry*>(hdr);
Assertion* ras = rentry->mAssertions;
Assertion* rprev = nullptr;
while (ras) {
if (ras == as) {
if (rprev) {
rprev->u.as.mInvNext = ras->u.as.mInvNext;
}
else {
// it's the first one. update the hashtable entry.
rentry->mAssertions = ras->u.as.mInvNext;
}
as->u.as.mInvNext = nullptr; // for my sanity.
break;
}
rprev = ras;
ras = ras->u.as.mInvNext;
}
// Wow, it was the _only_ one. Unhash it.
if (! rentry->mAssertions) {
PL_DHashTableRawRemove(aInfo->mReverseArcs, hdr);
}
// add to the list of assertions to unassert
as->mNext = aInfo->mUnassertList;
aInfo->mUnassertList = as;
// Advance to the next assertion
as = next;
}
}
// Wow, it was the _only_ one. Unhash it.
if (! rentry->mAssertions)
{
PL_DHashTableRawRemove(info->mReverseArcs, hdr);
}
// add to the list of assertions to unassert
as->mNext = info->mUnassertList;
info->mUnassertList = as;
// Advance to the next assertion
as = next;
// if no more assertions exist for this resource, then unhash it.
if (! entry->mAssertions) {
iter.Remove();
}
}
// if no more assertions exist for this resource, then unhash it.
if (! entry->mAssertions)
result = PL_DHASH_REMOVE;
return result;
}
////////////////////////////////////////////////////////////////////////
// rdfIDataSource methods
class VisitorClosure
{
public:
explicit VisitorClosure(rdfITripleVisitor* aVisitor) :
mVisitor(aVisitor),
mRv(NS_OK)
{}
rdfITripleVisitor* mVisitor;
nsresult mRv;
};
PLDHashOperator
SubjectEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg) {
Entry* entry = static_cast<Entry*>(aHdr);
VisitorClosure* closure = static_cast<VisitorClosure*>(aArg);
nsresult rv;
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv);
NS_ENSURE_SUCCESS(rv, PL_DHASH_NEXT);
closure->mRv = closure->mVisitor->Visit(subject, nullptr, nullptr, true);
if (NS_FAILED(closure->mRv) || closure->mRv == NS_RDF_STOP_VISIT)
return PL_DHASH_STOP;
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
InMemoryDataSource::VisitAllSubjects(rdfITripleVisitor *aVisitor)
{
@@ -1980,78 +1895,27 @@ InMemoryDataSource::VisitAllSubjects(rdfITripleVisitor *aVisitor)
++mReadCount;
// Enumerate all of our entries into an nsISupportsArray.
VisitorClosure cls(aVisitor);
PL_DHashTableEnumerate(&mForwardArcs, SubjectEnumerator, &cls);
nsresult rv = NS_OK;
for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<Entry*>(iter.Get());
nsresult rv2;
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv2);
if (NS_FAILED(rv2)) {
NS_WARNING("QI to nsIRDFNode failed");
continue;
}
rv = aVisitor->Visit(subject, nullptr, nullptr, true);
if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) {
break;
}
}
// Unlock datasource
--mReadCount;
return cls.mRv;
}
class TriplesInnerClosure
{
public:
TriplesInnerClosure(nsIRDFNode* aSubject, VisitorClosure* aClosure) :
mSubject(aSubject), mOuter(aClosure) {}
nsIRDFNode* mSubject;
VisitorClosure* mOuter;
};
PLDHashOperator
TriplesInnerEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg) {
Entry* entry = static_cast<Entry*>(aHdr);
Assertion* assertion = entry->mAssertions;
TriplesInnerClosure* closure =
static_cast<TriplesInnerClosure*>(aArg);
while (assertion) {
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
VisitorClosure* cls = closure->mOuter;
cls->mRv = cls->mVisitor->Visit(closure->mSubject,
assertion->u.as.mProperty,
assertion->u.as.mTarget,
assertion->u.as.mTruthValue);
if (NS_FAILED(cls->mRv) || cls->mRv == NS_RDF_STOP_VISIT) {
return PL_DHASH_STOP;
}
assertion = assertion->mNext;
}
return PL_DHASH_NEXT;
return rv;
}
PLDHashOperator
TriplesEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
uint32_t aNumber, void* aArg) {
Entry* entry = static_cast<Entry*>(aHdr);
VisitorClosure* closure = static_cast<VisitorClosure*>(aArg);
nsresult rv;
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv);
NS_ENSURE_SUCCESS(rv, PL_DHASH_NEXT);
if (entry->mAssertions->mHashEntry) {
TriplesInnerClosure cls(subject, closure);
PL_DHashTableEnumerate(entry->mAssertions->u.hash.mPropertyHash,
TriplesInnerEnumerator, &cls);
if (NS_FAILED(closure->mRv)) {
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
Assertion* assertion = entry->mAssertions;
while (assertion) {
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
closure->mRv = closure->mVisitor->Visit(subject,
assertion->u.as.mProperty,
assertion->u.as.mTarget,
assertion->u.as.mTruthValue);
if (NS_FAILED(closure->mRv) || closure->mRv == NS_RDF_STOP_VISIT) {
return PL_DHASH_STOP;
}
assertion = assertion->mNext;
}
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
InMemoryDataSource::VisitAllTriples(rdfITripleVisitor *aVisitor)
{
@@ -2059,13 +1923,59 @@ InMemoryDataSource::VisitAllTriples(rdfITripleVisitor *aVisitor)
++mReadCount;
// Enumerate all of our entries into an nsISupportsArray.
VisitorClosure cls(aVisitor);
PL_DHashTableEnumerate(&mForwardArcs, TriplesEnumerator, &cls);
nsresult rv = NS_OK;
for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<Entry*>(iter.Get());
nsresult rv2;
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv2);
if (NS_FAILED(rv2)) {
NS_WARNING("QI to nsIRDFNode failed");
} else if (entry->mAssertions->mHashEntry) {
for (auto iter = entry->mAssertions->u.hash.mPropertyHash->Iter();
!iter.Done();
iter.Next()) {
auto entry = static_cast<Entry*>(iter.Get());
Assertion* assertion = entry->mAssertions;
while (assertion) {
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
rv = aVisitor->Visit(subject, assertion->u.as.mProperty,
assertion->u.as.mTarget,
assertion->u.as.mTruthValue);
if (NS_FAILED(rv)) {
goto end;
}
if (rv == NS_RDF_STOP_VISIT) {
goto inner_end;
}
assertion = assertion->mNext;
}
}
} else {
Assertion* assertion = entry->mAssertions;
while (assertion) {
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
rv = aVisitor->Visit(subject, assertion->u.as.mProperty,
assertion->u.as.mTarget,
assertion->u.as.mTruthValue);
if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) {
goto end;
}
assertion = assertion->mNext;
}
}
inner_end:
(void) 0;
}
end:
// Unlock datasource
--mReadCount;
return cls.mRv;
return rv;
}
////////////////////////////////////////////////////////////////////////