tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 0e183810c4857a2e2b012a3a9de76b8572152944
parent a12d799f5b9b6d96025791ceaf5daa3ffb634c99
Author: agoloman <agoloman@mozilla.com>
Date:   Mon,  5 Jan 2026 20:49:07 +0200

Revert "Bug 2008530 - Part 2 - Use `nsGlyphTable::IsUnicodeTable()` instead of raw pointer comparison. r=layout-reviewers,dshin,sergesanspaille" for causing build bustages @nsMathMLChar.cpp.

This reverts commit 7a3c4b556acb00cc3a6f067e0a394d3a7ad898eb.

Revert "Bug 2008530 - Part 1 Statically initialize the MathML unicode table for stretchy operators. r=layout-reviewers,dshin"

This reverts commit 2e216f0f8869446dee03f3d12f233dfdbbe5cfb8.

Revert "Bug 2006706 - Document OOM Handling reality r=jandem"

This reverts commit c96f3ae833a3612015ea23101b651699904b66ae.

Diffstat:
Mjs/public/Exception.h | 34----------------------------------
Mlayout/mathml/nsMathMLChar.cpp | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
2 files changed, 125 insertions(+), 64 deletions(-)

diff --git a/js/public/Exception.h b/js/public/Exception.h @@ -31,42 +31,8 @@ enum class ExceptionStackBehavior : bool { extern JS_PUBLIC_API bool JS_IsExceptionPending(JSContext* cx); -// [SMDOC] Out Of Memory (OOM) Handling -// -// Many functions in SpiderMonkey can throw exceptions, and sometimes -// the exception thrown is out of memory. Unlike other exceptions, -// this is not an object, but rather the literal string "out of memory". -// -// **Out of Memory handling in SpiderMonkey is best-effort!** -// -// While the developers of SpiderMonkey do attempt to convert various scenarios -// into OutOfMemory calls, such that embedders can attempt to do some sort of -// recovery, we do not guarantee this in all cases. -// -// There are some places where attempting to convey OOM is challenging -// or where it would leave the engine in a state with invariants -// no longer holding. In those cases **the process will crash**. -// -// An example, though not comprehensive, signal of this to a curious -// reader would be AutoEnterOOMUnsafeRegion, which flags various -// places developers have indicated that crashing is better than -// throwing OOM. -// -// Currently we endeavour to always throw out-of-memory when we -// encounter GC heap limits. We also will sometimes throw OOM -// exceptions for things which are not really OOM: For example -// our executable code limits. -// -// It is important to not rely on OOM generation in SpiderMonkey -// as your only reliability measure, as it is not guaranteed. - -// Check for pending out of memory exception. extern JS_PUBLIC_API bool JS_IsThrowingOutOfMemory(JSContext* cx); -// Try and get the pending exception. This can return false -// if there is no pending exception -or- if there is a problem -// attempting to produce the exception (for example if wrapping -// the exception fails.) extern JS_PUBLIC_API bool JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp); diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp @@ -23,6 +23,7 @@ #include "mozilla/dom/Document.h" #include "mozilla/gfx/2D.h" #include "mozilla/intl/UnicodeScriptCodes.h" +#include "nsCOMPtr.h" #include "nsCSSRendering.h" #include "nsContentUtils.h" #include "nsDeviceContext.h" @@ -73,7 +74,6 @@ static const nsGlyphCode kNullGlyph = {{0}, false}; class nsGlyphTable { public: virtual ~nsGlyphTable() = default; - virtual bool IsUnicodeTable() const { return false; } virtual const nsCString& FontNameFor(const nsGlyphCode& aGlyphCode) const = 0; @@ -97,10 +97,16 @@ class nsGlyphTable { gfxFontGroup* aFontGroup, const nsGlyphCode& aGlyph) = 0; protected: + nsGlyphTable() : mCharCache(0), mFlags(gfx::ShapedTextFlags()) {} + explicit nsGlyphTable(gfx::ShapedTextFlags aFlags) + : mCharCache(0), mFlags(aFlags) {} + // For speedy re-use, we always cache the last data used in the table. // mCharCache is the Unicode point of the last char that was queried in this // table. - char16_t mCharCache = 0; + char16_t mCharCache; + + gfx::ShapedTextFlags mFlags; }; // A Unicode construction is a set of all the stretchy MathML characters that @@ -168,12 +174,10 @@ static const UnicodeConstruction gUnicodeTableConstructions[] = { class nsUnicodeTable final : public nsGlyphTable { public: - constexpr nsUnicodeTable() { MOZ_COUNT_CTOR(nsUnicodeTable); } + nsUnicodeTable() { MOZ_COUNT_CTOR(nsUnicodeTable); } MOZ_COUNTED_DTOR(nsUnicodeTable) - bool IsUnicodeTable() const final { return true; }; - const nsCString& FontNameFor(const nsGlyphCode& aGlyphCode) const override { MOZ_ASSERT_UNREACHABLE(); return VoidCString(); @@ -228,11 +232,9 @@ class nsUnicodeTable final : public nsGlyphTable { : mTarget(aTarget) {} const char16_t mTarget; }; - size_t mCachedIndex = 0; + size_t mCachedIndex; }; -static constinit nsUnicodeTable gUnicodeTable; - /* virtual */ nsGlyphCode nsUnicodeTable::ElementAt(DrawTarget* /* aDrawTarget */, int32_t /* aAppUnitsPerDevPixel */, @@ -270,7 +272,7 @@ already_AddRefed<gfxTextRun> nsUnicodeTable::MakeTextRun( NS_ASSERTION(!aGlyph.isGlyphID, "nsUnicodeTable can only access glyphs by code point"); return aFontGroup->MakeTextRun(&aGlyph.code, 1, aDrawTarget, - aAppUnitsPerDevPixel, gfx::ShapedTextFlags(), + aAppUnitsPerDevPixel, mFlags, nsTextFrameUtils::Flags(), nullptr); } @@ -319,13 +321,12 @@ class nsOpenTypeTable final : public nsGlyphTable { RefPtr<gfxFont> mFont; nsCString mFontFamilyName; uint32_t mGlyphID; - gfx::ShapedTextFlags mFlags; nsOpenTypeTable(gfxFont* aFont, gfx::ShapedTextFlags aFlags) - : mFont(aFont), + : nsGlyphTable(aFlags), + mFont(aFont), mFontFamilyName(aFont->GetFontEntry()->FamilyName()), - mGlyphID(0), - mFlags(aFlags) { + mGlyphID(0) { MOZ_COUNT_CTOR(nsOpenTypeTable); } @@ -438,6 +439,96 @@ already_AddRefed<gfxTextRun> nsOpenTypeTable::MakeTextRun( } // ----------------------------------------------------------------------------- +// This is the list of all the applicable glyph tables. +// We will maintain a single global instance that will only reveal those +// glyph tables that are associated to fonts currently installed on the +// user' system. The class is an XPCOM shutdown observer to allow us to +// free its allocated data at shutdown + +class nsGlyphTableList final : public nsIObserver { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + nsUnicodeTable mUnicodeTable; + + nsGlyphTableList() {} + + nsresult Initialize(); + nsresult Finalize(); + + private: + ~nsGlyphTableList() = default; +}; + +NS_IMPL_ISUPPORTS(nsGlyphTableList, nsIObserver) + +// ----------------------------------------------------------------------------- +// Here is the global list of applicable glyph tables that we will be using +static nsGlyphTableList* gGlyphTableList = nullptr; + +static bool gGlyphTableInitialized = false; + +// XPCOM shutdown observer +NS_IMETHODIMP +nsGlyphTableList::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* someData) { + Finalize(); + return NS_OK; +} + +// Add an observer to XPCOM shutdown so that we can free our data at shutdown +nsresult nsGlyphTableList::Initialize() { + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (!obs) { + return NS_ERROR_FAILURE; + } + + nsresult rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +// Remove our observer and free the memory that were allocated for us +nsresult nsGlyphTableList::Finalize() { + // Remove our observer from the observer service + nsresult rv = NS_OK; + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (obs) { + rv = obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); + } else { + rv = NS_ERROR_FAILURE; + } + + gGlyphTableInitialized = false; + // our oneself will be destroyed when our |Release| is called by the observer + NS_IF_RELEASE(gGlyphTableList); + return rv; +} + +// ----------------------------------------------------------------------------- + +static nsresult InitCharGlobals() { + NS_ASSERTION(!gGlyphTableInitialized, "Error -- already initialized"); + gGlyphTableInitialized = true; + + // Allocate the placeholders for the preferred parts and variants + nsresult rv = NS_ERROR_OUT_OF_MEMORY; + auto glyphTableList = MakeRefPtr<nsGlyphTableList>(); + if (glyphTableList) { + rv = glyphTableList->Initialize(); + } + if (NS_FAILED(rv)) { + return rv; + } + // The gGlyphTableList has been successfully registered as a shutdown + // observer and will be deleted at shutdown. + glyphTableList.forget(&gGlyphTableList); + return rv; +} + +// ----------------------------------------------------------------------------- // And now the implementation of nsMathMLChar nsMathMLChar::~nsMathMLChar() { MOZ_COUNT_DTOR(nsMathMLChar); } @@ -453,13 +544,16 @@ void nsMathMLChar::SetComputedStyle(ComputedStyle* aComputedStyle) { } void nsMathMLChar::SetData(nsString& aData) { + if (!gGlyphTableInitialized) { + InitCharGlobals(); + } mData = aData; // some assumptions until proven otherwise // note that mGlyph is not initialized mDirection = NS_STRETCH_DIRECTION_UNSUPPORTED; mBoundingMetrics = nsBoundingMetrics(); // check if stretching is applicable ... - if (1 == mData.Length()) { + if (gGlyphTableList && (1 == mData.Length())) { mDirection = nsMathMLOperators::GetStretchyDirection(mData); // default tentative table (not the one that is necessarily going // to be used) @@ -664,7 +758,7 @@ bool nsMathMLChar::SetFontFamily(nsPresContext* aPresContext, // Set the font if it is an unicode table or if the same family name has // been found. const bool shouldSetFont = [&] { - if (aGlyphTable && aGlyphTable->IsUnicodeTable()) { + if (aGlyphTable == &gGlyphTableList->mUnicodeTable) { return true; } @@ -940,7 +1034,7 @@ bool nsMathMLChar::StretchEnumContext::TryParts( // For the Unicode table, we check that all the glyphs are actually found and // come from the same font. - if (aGlyphTable->IsUnicodeTable()) { + if (aGlyphTable == &gGlyphTableList->mUnicodeTable) { gfxFont* unicodeFont = nullptr; for (int32_t i = 0; i < 4; i++) { if (!textRun[i]) { @@ -1095,20 +1189,20 @@ bool nsMathMLChar::StretchEnumContext::EnumCallback( // Determine the glyph table to use for this font. UniquePtr<nsOpenTypeTable> openTypeTable; - auto glyphTable = [&aFamily, &fontGroup, &openTypeTable, - &aFlags]() -> nsGlyphTable* { - if (!aFamily.IsGeneric()) { - // If the font contains an Open Type MATH table, use it. - RefPtr<gfxFont> font = fontGroup->GetFirstValidFont(); - openTypeTable = nsOpenTypeTable::Create(font, aFlags); - if (openTypeTable) { - return openTypeTable.get(); - } + nsGlyphTable* glyphTable; + if (aFamily.IsGeneric()) { + // This is a generic font, use the Unicode table. + glyphTable = &gGlyphTableList->mUnicodeTable; + } else { + // If the font contains an Open Type MATH table, use it. + RefPtr<gfxFont> font = fontGroup->GetFirstValidFont(); + openTypeTable = nsOpenTypeTable::Create(font, aFlags); + if (openTypeTable) { + glyphTable = openTypeTable.get(); + } else { + glyphTable = &gGlyphTableList->mUnicodeTable; } - // Fallback to the Unicode table. - return &gUnicodeTable; - }(); - MOZ_ASSERT(glyphTable); + } if (!openTypeTable) { // Make sure we only try the UnicodeTable once. @@ -1122,7 +1216,8 @@ bool nsMathMLChar::StretchEnumContext::EnumCallback( // special table is being used then the font in this family should have the // specified glyphs. const StyleFontFamilyList& familyList = - glyphTable->IsUnicodeTable() ? context->mFamilyList : family; + glyphTable == &gGlyphTableList->mUnicodeTable ? context->mFamilyList + : family; return (context->mTryVariants && context->TryVariants(glyphTable, &fontGroup, familyList, aRtl)) ||