author | Dorel Luca <dluca@mozilla.com> |
Wed, 16 May 2018 00:54:22 +0300 | |
changeset 418398 | 380cf87c1ee3966dd94499942b73085754dc4824 |
parent 418352 | 9260cc524bb54d9318075578488de8a6f40677eb (current diff) |
parent 418397 | 12bfd7a50a79e0509aabf9e97b72013a93d747d4 (diff) |
child 418415 | 0acb9d9da524201f2199be02f71fe23c577549ec |
child 418450 | 2404129f5672b9a91ea006c3f51cf171833a3124 |
push id | 33999 |
push user | dluca@mozilla.com |
push date | Tue, 15 May 2018 21:54:51 +0000 |
treeherder | mozilla-central@380cf87c1ee3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 62.0a1 |
first release with | nightly linux32
380cf87c1ee3
/
62.0a1
/
20180515220059
/
files
nightly linux64
380cf87c1ee3
/
62.0a1
/
20180515220059
/
files
nightly mac
380cf87c1ee3
/
62.0a1
/
20180515220059
/
files
nightly win32
380cf87c1ee3
/
62.0a1
/
20180515220059
/
files
nightly win64
380cf87c1ee3
/
62.0a1
/
20180515220059
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
62.0a1
/
20180515220059
/
pushlog to previous
nightly linux64
62.0a1
/
20180515220059
/
pushlog to previous
nightly mac
62.0a1
/
20180515220059
/
pushlog to previous
nightly win32
62.0a1
/
20180515220059
/
pushlog to previous
nightly win64
62.0a1
/
20180515220059
/
pushlog to previous
|
--- a/Makefile.in +++ b/Makefile.in @@ -28,18 +28,18 @@ DIST_GARBAGE = config.cache config.log c config/autoconf.mk \ mozilla-config.h \ netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \ .mozconfig.mk ifndef MOZ_PROFILE_USE # Automation builds should always have a new buildid, but for the sake of not # re-linking libxul on every incremental build we do not enforce this for -# developer builds. -ifneq (,$(MOZ_AUTOMATION)$(MOZ_BUILD_DATE)) +# developer builds. Tests always need a new buildid as well. +ifneq (,$(MOZ_AUTOMATION)$(MOZ_BUILD_DATE)$(TEST_MOZBUILD)) buildid.h source-repo.h: FORCE endif endif ifdef JS_STANDALONE configure_dir = $(topsrcdir)/js/src else configure_dir = $(topsrcdir) @@ -104,17 +104,17 @@ include $(topsrcdir)/build/rebuild-backe Makefile: $(BUILD_BACKEND_FILES) @$(TOUCH) $@ default:: $(BUILD_BACKEND_FILES) endif install_manifests := \ - $(addprefix dist/,branding idl include public private xpi-stage) \ + $(addprefix dist/,branding include public private xpi-stage) \ _tests \ $(NULL) # Skip the dist/bin install manifest when using the hybrid # FasterMake/RecursiveMake backend. This is a hack until bug 1241744 moves # xpidl handling to FasterMake in that case, mechanically making the dist/bin # install manifest non-existent (non-existent manifests being skipped) ifeq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS))) install_manifests += dist/bin @@ -135,22 +135,20 @@ install_manifest_depends += \ endif endif .PHONY: install-manifests install-manifests: $(addprefix install-,$(install_manifests)) # If we're using the hybrid FasterMake/RecursiveMake backend, we want # to recurse in the faster/ directory in parallel of install manifests. -# But dist/idl needs to happen before (cf. dependencies in -# config/faster/rules.mk) ifneq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS))) install-manifests: faster .PHONY: faster -faster: install-dist/idl +faster: $(MAKE) -C faster FASTER_RECURSIVE_MAKE=1 endif .PHONY: $(addprefix install-,$(install_manifests)) $(addprefix install-,$(install_manifests)): install-%: $(install_manifest_depends) ifneq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS))) @# If we're using the hybrid FasterMake/RecursiveMake backend, we want @# to ensure the FasterMake end doesn't have install manifests for the
--- a/accessible/base/AccIterator.cpp +++ b/accessible/base/AccIterator.cpp @@ -377,17 +377,17 @@ ItemIterator::Next() return mAnchor ? (mAnchor = AccGroupInfo::NextItemTo(mAnchor)) : nullptr; } //////////////////////////////////////////////////////////////////////////////// // XULTreeItemIterator //////////////////////////////////////////////////////////////////////////////// -XULTreeItemIterator::XULTreeItemIterator(XULTreeAccessible* aXULTree, +XULTreeItemIterator::XULTreeItemIterator(const XULTreeAccessible* aXULTree, nsITreeView* aTreeView, int32_t aRowIdx) : mXULTree(aXULTree), mTreeView(aTreeView), mRowCount(-1), mContainerLevel(-1), mCurrRowIdx(aRowIdx + 1) { mTreeView->GetRowCount(&mRowCount); if (aRowIdx != -1) mTreeView->GetLevel(aRowIdx, &mContainerLevel);
--- a/accessible/base/AccIterator.h +++ b/accessible/base/AccIterator.h @@ -296,28 +296,28 @@ private: /** * Used to iterate through XUL tree items of the same level. */ class XULTreeItemIterator : public AccIterable { public: - XULTreeItemIterator(XULTreeAccessible* aXULTree, nsITreeView* aTreeView, + XULTreeItemIterator(const XULTreeAccessible* aXULTree, nsITreeView* aTreeView, int32_t aRowIdx); virtual ~XULTreeItemIterator() { } virtual Accessible* Next() override; private: XULTreeItemIterator() = delete; XULTreeItemIterator(const XULTreeItemIterator&) = delete; XULTreeItemIterator& operator = (const XULTreeItemIterator&) = delete; - XULTreeAccessible* mXULTree; + const XULTreeAccessible* mXULTree; nsITreeView* mTreeView; int32_t mRowCount; int32_t mContainerLevel; int32_t mCurrRowIdx; }; } // namespace a11y } // namespace mozilla
--- a/accessible/base/MarkupMap.h +++ b/accessible/base/MarkupMap.h @@ -322,17 +322,18 @@ MARKUPMAP(section, MARKUPMAP(summary, New_HTMLSummary, roles::SUMMARY) MARKUPMAP( table, [](Element* aElement, Accessible* aContext) -> Accessible* { - if (aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableType) { + if (aElement->GetPrimaryFrame() && + aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableType) { return new ARIAGridAccessibleWrap(aElement, aContext->Document()); } return nullptr; }, 0 ) MARKUPMAP(time, @@ -385,22 +386,23 @@ MARKUPMAP( // CreateAccessibleByFrameType dual logic. Accessible* table = aContext->IsTable() ? aContext : nullptr; if (!table && aContext->Parent() && aContext->Parent()->IsTable()) { table = aContext->Parent(); } if (table) { nsIContent* parentContent = aElement->GetParent(); nsIFrame* parentFrame = parentContent->GetPrimaryFrame(); - if (!parentFrame->IsTableWrapperFrame()) { + if (parentFrame && !parentFrame->IsTableWrapperFrame()) { parentContent = parentContent->GetParent(); parentFrame = parentContent->GetPrimaryFrame(); if (table->GetContent() == parentContent && - (!parentFrame->IsTableWrapperFrame() || - aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableRowType)) { + ((parentFrame && !parentFrame->IsTableWrapperFrame()) || + (aElement->GetPrimaryFrame() && + aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableRowType))) { return new ARIARowAccessible(aElement, aContext->Document()); } } } return nullptr; }, 0 )
--- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -1049,16 +1049,30 @@ nsAccessibilityService::CreateAccessible return nullptr; nsIContent* content = aNode->AsContent(); nsIFrame* frame = content->GetPrimaryFrame(); // Check frame and its visibility. Note, hidden frame allows visible // elements in subtree. if (!frame || !frame->StyleVisibility()->IsVisible()) { + // display:contents element doesn't have a frame, but retains the semantics. + // All its children are unaffected. + if (content->IsElement() && content->AsElement()->IsDisplayContents()) { + const HTMLMarkupMapInfo* markupMap = + mHTMLMarkupMap.Get(content->NodeInfo()->NameAtom()); + if (markupMap && markupMap->new_func) { + RefPtr<Accessible> newAcc = + markupMap->new_func(content->AsElement(), aContext); + document->BindToDocument(newAcc, aria::GetRoleMap(content->AsElement())); + return newAcc; + } + return nullptr; + } + if (aIsSubtreeHidden && !frame) *aIsSubtreeHidden = true; return nullptr; } if (frame->GetContent() != content) { // Not the main content for this frame. This happens because <area>
--- a/accessible/generic/Accessible.cpp +++ b/accessible/generic/Accessible.cpp @@ -319,18 +319,24 @@ Accessible::TranslateString(const nsStri if (NS_SUCCEEDED(rv)) aStringOut.Assign(xsValue); } uint64_t Accessible::VisibilityState() const { nsIFrame* frame = GetFrame(); - if (!frame) + if (!frame) { + // Element having display:contents is considered visible semantically, + // despite it doesn't have a visually visible box. + if (mContent->IsElement() && mContent->AsElement()->IsDisplayContents()) { + return states::OFFSCREEN; + } return states::INVISIBLE; + } // Walk the parent frame chain to see if there's invisible parent or the frame // is in background tab. if (!frame->StyleVisibility()->IsVisible()) return states::INVISIBLE; // Offscreen state if the document's visibility state is not visible. if (Document()->IsHidden()) @@ -1941,18 +1947,22 @@ Accessible::AppendTextTo(nsAString& aTex uint32_t aLength) { // Return text representation of non-text accessible within hypertext // accessible. Text accessible overrides this method to return enclosed text. if (aStartOffset != 0 || aLength == 0) return; nsIFrame *frame = GetFrame(); - if (!frame) + if (!frame) { + if (mContent->IsElement() && mContent->AsElement()->IsDisplayContents()) { + aText += kEmbeddedObjectChar; + } return; + } NS_ASSERTION(mParent, "Called on accessible unbound from tree. Result can be wrong."); if (frame->IsBrFrame()) { aText += kForcedNewLineChar; } else if (mParent && nsAccUtils::MustPrune(mParent)) { // Expose the embedded object accessible as imaginary embedded object @@ -2559,17 +2569,17 @@ bool Accessible::AreItemsOperable() const { return HasOwnContent() && mContent->IsElement() && mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant); } Accessible* -Accessible::CurrentItem() +Accessible::CurrentItem() const { // Check for aria-activedescendant, which changes which element has focus. // For activedescendant, the ARIA spec does not require that the user agent // checks whether pointed node is actually a DOM descendant of the element // with the aria-activedescendant attribute. nsAutoString id; if (HasOwnContent() && mContent->IsElement() && @@ -2582,17 +2592,17 @@ Accessible::CurrentItem() if (document) return document->GetAccessible(activeDescendantElm); } } return nullptr; } void -Accessible::SetCurrentItem(Accessible* aItem) +Accessible::SetCurrentItem(const Accessible* aItem) { nsAtom* id = aItem->GetContent()->GetID(); if (id) { nsAutoString idStr; id->ToString(idStr); mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant, idStr,
--- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -430,17 +430,17 @@ public: /** * Return index in parent accessible. */ virtual int32_t IndexInParent() const; /** * Return true if accessible has children; */ - bool HasChildren() { return !!GetChildAt(0); } + bool HasChildren() const { return !!GetChildAt(0); } /** * Return first/last/next/previous sibling of the accessible. */ inline Accessible* NextSibling() const { return GetSiblingAtOffset(1); } inline Accessible* PrevSibling() const { return GetSiblingAtOffset(-1); } @@ -845,22 +845,22 @@ public: * can be activated. */ virtual bool AreItemsOperable() const; /** * Return the current item of the widget, i.e. an item that has or will have * keyboard focus when widget gets active. */ - virtual Accessible* CurrentItem(); + virtual Accessible* CurrentItem() const; /** * Set the current item of the widget. */ - virtual void SetCurrentItem(Accessible* aItem); + virtual void SetCurrentItem(const Accessible* aItem); /** * Return container widget this accessible belongs to. */ virtual Accessible* ContainerWidget() const; /** * Return the localized string for the given key.
--- a/accessible/generic/RootAccessible.cpp +++ b/accessible/generic/RootAccessible.cpp @@ -97,17 +97,17 @@ RootAccessible::NativeRole() const return roles::DIALOG; return DocAccessibleWrap::NativeRole(); } // RootAccessible protected member #ifdef MOZ_XUL uint32_t -RootAccessible::GetChromeFlags() +RootAccessible::GetChromeFlags() const { // Return the flag set for the top level window as defined // by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME] // Not simple: nsIXULWindow is not just a QI from nsIDOMWindow nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mDocumentNode); NS_ENSURE_TRUE(docShell, 0); nsCOMPtr<nsIDocShellTreeOwner> treeOwner; docShell->GetTreeOwner(getter_AddRefs(treeOwner));
--- a/accessible/generic/RootAccessible.h +++ b/accessible/generic/RootAccessible.h @@ -71,17 +71,17 @@ protected: void HandlePopupHidingEvent(nsINode* aNode); #ifdef MOZ_XUL void HandleTreeRowCountChangedEvent(dom::Event* aEvent, XULTreeAccessible* aAccessible); void HandleTreeInvalidatedEvent(dom::Event* aEvent, XULTreeAccessible* aAccessible); - uint32_t GetChromeFlags(); + uint32_t GetChromeFlags() const; #endif }; inline RootAccessible* Accessible::AsRoot() { return IsRoot() ? static_cast<mozilla::a11y::RootAccessible*>(this) : nullptr; }
--- a/accessible/html/HTMLSelectAccessible.cpp +++ b/accessible/html/HTMLSelectAccessible.cpp @@ -88,32 +88,32 @@ HTMLSelectListAccessible::IsActiveWidget bool HTMLSelectListAccessible::AreItemsOperable() const { return true; } Accessible* -HTMLSelectListAccessible::CurrentItem() +HTMLSelectListAccessible::CurrentItem() const { nsIListControlFrame* listControlFrame = do_QueryFrame(GetFrame()); if (listControlFrame) { nsCOMPtr<nsIContent> activeOptionNode = listControlFrame->GetCurrentOption(); if (activeOptionNode) { DocAccessible* document = Document(); if (document) return document->GetAccessible(activeOptionNode); } } return nullptr; } void -HTMLSelectListAccessible::SetCurrentItem(Accessible* aItem) +HTMLSelectListAccessible::SetCurrentItem(const Accessible* aItem) { if (!aItem->GetContent()->IsElement()) return; aItem->GetContent()->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::selected, NS_LITERAL_STRING("true"), true); @@ -495,23 +495,23 @@ HTMLComboboxAccessible::IsActiveWidget() bool HTMLComboboxAccessible::AreItemsOperable() const { nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(GetFrame()); return comboboxFrame && comboboxFrame->IsDroppedDown(); } Accessible* -HTMLComboboxAccessible::CurrentItem() +HTMLComboboxAccessible::CurrentItem() const { return AreItemsOperable() ? mListAccessible->CurrentItem() : nullptr; } void -HTMLComboboxAccessible::SetCurrentItem(Accessible* aItem) +HTMLComboboxAccessible::SetCurrentItem(const Accessible* aItem) { if (AreItemsOperable()) mListAccessible->SetCurrentItem(aItem); } //////////////////////////////////////////////////////////////////////////////// // HTMLComboboxAccessible: protected
--- a/accessible/html/HTMLSelectAccessible.h +++ b/accessible/html/HTMLSelectAccessible.h @@ -44,18 +44,18 @@ public: // SelectAccessible virtual bool SelectAll() override; virtual bool UnselectAll() override; // Widgets virtual bool IsWidget() const override; virtual bool IsActiveWidget() const override; virtual bool AreItemsOperable() const override; - virtual Accessible* CurrentItem() override; - virtual void SetCurrentItem(Accessible* aItem) override; + virtual Accessible* CurrentItem() const override; + virtual void SetCurrentItem(const Accessible* aItem) override; }; /* * Options inside the select, contained within the list */ class HTMLSelectOptionAccessible : public HyperTextAccessibleWrap { public: @@ -175,18 +175,18 @@ public: virtual uint8_t ActionCount() override; virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override; virtual bool DoAction(uint8_t aIndex) override; // Widgets virtual bool IsWidget() const override; virtual bool IsActiveWidget() const override; virtual bool AreItemsOperable() const override; - virtual Accessible* CurrentItem() override; - virtual void SetCurrentItem(Accessible* aItem) override; + virtual Accessible* CurrentItem() const override; + virtual void SetCurrentItem(const Accessible* aItem) override; protected: /** * Return selected option. */ Accessible* SelectedOption() const; private:
--- a/accessible/tests/mochitest/states/test_visibility.html +++ b/accessible/tests/mochitest/states/test_visibility.html @@ -18,16 +18,17 @@ <script type="application/javascript"> // Tests function doTests() { testStates("div", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); testStates("div_off", STATE_OFFSCREEN, 0, STATE_INVISIBLE); testStates("div_transformed", STATE_OFFSCREEN, 0, STATE_INVISIBLE); testStates("div_abschild", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN); + testStates("ul", STATE_OFFSCREEN, 0, STATE_INVISIBLE); SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTests); </script> @@ -61,11 +62,15 @@ transformed! </div> <!-- edge case: no rect but has out of flow child --> <div id="div_abschild"> <p style="position: absolute; left: 120px; top:120px;">absolute</p> </div> + <ul id="ul" style="display: contents;"> + <li>Supermarket 1</li> + <li>Supermarket 2</li> + </ul> </div> </body> </html>
--- a/accessible/tests/mochitest/text/test_hypertext.html +++ b/accessible/tests/mochitest/text/test_hypertext.html @@ -34,17 +34,17 @@ // //////////////////////////////////////////////////////////////////////// // hypertext // //////////////////////////////////////////////////////////////////////// // ! - embedded object char // __h__e__l__l__o__ __!__ __s__e__e__ __!__ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 - var IDs = [ "hypertext", "hypertext2" ]; + var IDs = [ "hypertext", "hypertext2", "ht_displaycontents" ]; // ////////////////////////////////////////////////////////////////////// // characterCount testCharacterCount(IDs, 13); // ////////////////////////////////////////////////////////////////////// // getText @@ -118,16 +118,20 @@ <div id="content" style="display: none"></div> <pre id="test"> </pre> <div id="nulltext"></div> <div id="hypertext">hello <a>friend</a> see <img src="about:blank"></div> <div id="hypertext2">hello <a>friend</a> see <input></div> + <div id="ht_displaycontents">hello <a>friend</a> see <ul id="ul" style="display: contents;"> + <li>Supermarket 1</li> + <li>Supermarket 2</li> + </ul></div> <ol id="list"> <li id="listitem">foo</li> <li id="listitemnone">bar</li> </ol> <div id="hypertext3">line <!-- haha --> <!-- hahaha -->
--- a/accessible/tests/mochitest/tree/a11y.ini +++ b/accessible/tests/mochitest/tree/a11y.ini @@ -20,16 +20,17 @@ skip-if = true # Bug 561508 [test_aria_presentation.html] [test_aria_table.html] [test_brokencontext.html] [test_button.xul] [test_canvas.html] [test_combobox.xul] [test_cssflexbox.html] [test_cssoverflow.html] +[test_display_contents.html] [test_dochierarchy.html] [test_dockids.html] [test_filectrl.html] [test_formctrl.html] skip-if = buildapp == "mulet" [test_formctrl.xul] [test_gencontent.html] [test_groupbox.xul]
new file mode 100644 --- /dev/null +++ b/accessible/tests/mochitest/tree/test_display_contents.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html> + +<head> +<title>CSS display:contents tests</title> +<link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + +<script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<script type="application/javascript" + src="../common.js"></script> +<script type="application/javascript" + src="../role.js"></script> + +<script type="application/javascript"> +function doTest() { + let tree = + { LIST: [ + { LISTITEM: [ + { STATICTEXT: [] }, + { TEXT_LEAF: [] } + ]}, + { LISTITEM: [ + { STATICTEXT: [] }, + { TEXT_LEAF: [] } + ]}, + ] }; + testAccessibleTree("ul", tree); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addA11yLoadEvent(doTest); +</script> +</head> +<body> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <ul id="ul" style="display: contents;"> + <li>Supermarket 1</li> + <li>Supermarket 2</li> + </ul> +</body> +</html>
--- a/accessible/xul/XULMenuAccessible.cpp +++ b/accessible/xul/XULMenuAccessible.cpp @@ -568,26 +568,26 @@ XULMenubarAccessible::IsActiveWidget() c bool XULMenubarAccessible::AreItemsOperable() const { return true; } Accessible* -XULMenubarAccessible::CurrentItem() +XULMenubarAccessible::CurrentItem() const { nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame()); if (menuBarFrame) { nsMenuFrame* menuFrame = menuBarFrame->GetCurrentMenuItem(); if (menuFrame) { nsIContent* menuItemNode = menuFrame->GetContent(); return mDoc->GetAccessible(menuItemNode); } } return nullptr; } void -XULMenubarAccessible::SetCurrentItem(Accessible* aItem) +XULMenubarAccessible::SetCurrentItem(const Accessible* aItem) { NS_ERROR("XULMenubarAccessible::SetCurrentItem not implemented"); }
--- a/accessible/xul/XULMenuAccessible.h +++ b/accessible/xul/XULMenuAccessible.h @@ -103,18 +103,18 @@ public: XULMenubarAccessible(nsIContent* aContent, DocAccessible* aDoc); // Accessible virtual a11y::role NativeRole() const override; // Widget virtual bool IsActiveWidget() const override; virtual bool AreItemsOperable() const override; - virtual Accessible* CurrentItem() override; - virtual void SetCurrentItem(Accessible* aItem) override; + virtual Accessible* CurrentItem() const override; + virtual void SetCurrentItem(const Accessible* aItem) override; protected: // Accessible virtual ENameValueFlag NativeName(nsString& aName) override; }; } // namespace a11y } // namespace mozilla
--- a/accessible/xul/XULSelectControlAccessible.cpp +++ b/accessible/xul/XULSelectControlAccessible.cpp @@ -206,17 +206,17 @@ XULSelectControlAccessible::SelectAll() // otherwise, don't support this method return false; } //////////////////////////////////////////////////////////////////////////////// // XULSelectControlAccessible: Widgets Accessible* -XULSelectControlAccessible::CurrentItem() +XULSelectControlAccessible::CurrentItem() const { if (!mSelectControl) return nullptr; nsCOMPtr<nsIDOMXULSelectControlItemElement> currentItemElm; nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = do_QueryInterface(mSelectControl); if (multiSelectControl) @@ -233,17 +233,17 @@ XULSelectControlAccessible::CurrentItem( if (document) return document->GetAccessible(DOMNode); } return nullptr; } void -XULSelectControlAccessible::SetCurrentItem(Accessible* aItem) +XULSelectControlAccessible::SetCurrentItem(const Accessible* aItem) { if (!mSelectControl) return; nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = do_QueryInterface(aItem->GetContent()); nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = do_QueryInterface(mSelectControl);
--- a/accessible/xul/XULSelectControlAccessible.h +++ b/accessible/xul/XULSelectControlAccessible.h @@ -31,18 +31,18 @@ public: virtual Accessible* GetSelectedItem(uint32_t aIndex) override; virtual bool IsItemSelected(uint32_t aIndex) override; virtual bool AddItemToSelection(uint32_t aIndex) override; virtual bool RemoveItemFromSelection(uint32_t aIndex) override; virtual bool SelectAll() override; virtual bool UnselectAll() override; // Widgets - virtual Accessible* CurrentItem() override; - virtual void SetCurrentItem(Accessible* aItem) override; + virtual Accessible* CurrentItem() const override; + virtual void SetCurrentItem(const Accessible* aItem) override; protected: // nsIDOMXULMultiSelectControlElement inherits from this, so we'll always have // one of these if the widget is valid and not defunct nsCOMPtr<nsIDOMXULSelectControlElement> mSelectControl; }; } // namespace a11y
--- a/accessible/xul/XULTreeAccessible.cpp +++ b/accessible/xul/XULTreeAccessible.cpp @@ -217,17 +217,17 @@ XULTreeAccessible::ChildAtPoint(int32_t return child; } //////////////////////////////////////////////////////////////////////////////// // XULTreeAccessible: SelectAccessible Accessible* -XULTreeAccessible::CurrentItem() +XULTreeAccessible::CurrentItem() const { if (!mTreeView) return nullptr; nsCOMPtr<nsITreeSelection> selection; mTreeView->GetSelection(getter_AddRefs(selection)); if (selection) { int32_t currentIndex = -1; @@ -235,17 +235,17 @@ XULTreeAccessible::CurrentItem() if (currentIndex >= 0) return GetTreeItemAccessible(currentIndex); } return nullptr; } void -XULTreeAccessible::SetCurrentItem(Accessible* aItem) +XULTreeAccessible::SetCurrentItem(const Accessible* aItem) { NS_ERROR("XULTreeAccessible::SetCurrentItem not implemented"); } void XULTreeAccessible::SelectedItems(nsTArray<Accessible*>* aItems) { if (!mTreeView)
--- a/accessible/xul/XULTreeAccessible.h +++ b/accessible/xul/XULTreeAccessible.h @@ -59,18 +59,18 @@ public: virtual bool RemoveItemFromSelection(uint32_t aIndex) override; virtual bool SelectAll() override; virtual bool UnselectAll() override; // Widgets virtual bool IsWidget() const override; virtual bool IsActiveWidget() const override; virtual bool AreItemsOperable() const override; - virtual Accessible* CurrentItem() override; - virtual void SetCurrentItem(Accessible* aItem) override; + virtual Accessible* CurrentItem() const override; + virtual void SetCurrentItem(const Accessible* aItem) override; virtual Accessible* ContainerWidget() const override; // XULTreeAccessible /** * Return tree item accessible at the givem row. If accessible doesn't exist * in the cache then create and cache it.
--- a/config/faster/rules.mk +++ b/config/faster/rules.mk @@ -92,24 +92,16 @@ ACDEFINES += -DBUILD_FASTER -DBOOKMARKS_INCLUDE_DIR=$(TOPSRCDIR)/browser/locales/en-US/profile \ $(ACDEFINES) \ install_$(subst /,_,$*) # ============================================================================ # Below is a set of additional dependencies and variables used to build things # that are not supported by data in moz.build. -# The xpidl target in config/makefiles/xpidl requires the install manifest for -# dist/idl to have been processed. When using the hybrid -# FasterMake/RecursiveMake backend, this dependency is handled in the top-level -# Makefile. -ifndef FASTER_RECURSIVE_MAKE -$(TOPOBJDIR)/config/makefiles/xpidl/xpidl: $(TOPOBJDIR)/install-dist_idl -endif - $(TOPOBJDIR)/build/application.ini: $(TOPOBJDIR)/buildid.h $(TOPOBJDIR)/source-repo.h # The manifest of allowed system add-ons should be re-built when using # "build faster". # # Note the dependency on install-dist/bin. The form of this # dependency is critical: it's triggering the stem rule (install-%) # above to force the dist/bin manifest to be processed. The more
--- a/config/makefiles/xpidl/Makefile.in +++ b/config/makefiles/xpidl/Makefile.in @@ -36,17 +36,18 @@ code_gen_deps := $(topsrcdir)/xpcom/refl # TODO we should use py_action, but that would require extra directories to be # in the virtualenv. %.xpt: $(REPORT_BUILD) $(PYTHON_PATH) $(PLY_INCLUDE) -I$(topsrcdir)/xpcom/idl-parser -I$(DEPTH)/xpcom/idl-parser/xpidl \ $(process_py) --cache-dir $(DEPTH)/xpcom/idl-parser/xpidl --depsdir $(idl_deps_dir) \ --bindings-conf $(topsrcdir)/dom/bindings/Bindings.conf \ - $(dist_idl_dir) $(dist_include_dir) $(dist_xpcrs_dir) $(@D) \ + $(foreach dir,$(all_idl_dirs),-I $(dir)) \ + $(dist_include_dir) $(dist_xpcrs_dir) $(@D) \ $(basename $(notdir $@)) $($(basename $(notdir $@))_deps) # When some IDL is added or removed, if the actual IDL file was already, or # still is, in the tree, simple dependencies can't detect that the XPT needs # to be rebuilt. # Add the current value of $($(xpidl_module)_deps) in the depend file, such that # we can later check if the value has changed since last build, which will # indicate whether IDLs were added or removed. # Note that removing previously built files is not covered. @@ -70,17 +71,16 @@ endif $(generated_file): $(xpt_files) $(code_gen_py) $(code_gen_deps) $(REPORT_BUILD) $(PYTHON_PATH) $(PLY_INCLUDE) $(code_gen_py) $(generated_file) $(xpt_files) -include $(depends_files) define xpt_deps $(1): $(call mkdir_deps,$(dir $(1))) -$(1): $(addsuffix .idl,$(addprefix $(dist_idl_dir)/,$($(basename $(notdir $(1)))_deps))) ifneq ($($(basename $(notdir $(1)))_deps),$($(basename $(notdir $(1)))_deps_built)) $(1): FORCE endif endef $(foreach xpt,$(xpt_files),$(eval $(call xpt_deps,$(xpt)))) .PHONY: xpidl
--- a/devtools/server/actors/object/previewers.js +++ b/devtools/server/actors/object/previewers.js @@ -541,17 +541,16 @@ previewers.Object = [ function ArrayLike({obj, hooks}, grip, rawObj) { if (isWorker || !rawObj || obj.class != "DOMStringList" && obj.class != "DOMTokenList" && obj.class != "CSSRuleList" && obj.class != "MediaList" && obj.class != "StyleSheetList" && - obj.class != "CSSValueList" && obj.class != "NamedNodeMap" && obj.class != "FileList" && obj.class != "NodeList") { return false; } if (typeof rawObj.length != "number") { return false;
--- a/dom/base/UseCounters.conf +++ b/dom/base/UseCounters.conf @@ -103,13 +103,14 @@ method console.table method console.trace method console.warn method console.dir method console.dirxml method console.group method console.groupCollapsed method console.groupEnd method console.time +method console.timeLog method console.timeEnd method console.exception method console.timeStamp method console.profile method console.profileEnd
--- a/dom/base/WindowNamedPropertiesHandler.cpp +++ b/dom/base/WindowNamedPropertiesHandler.cpp @@ -108,52 +108,50 @@ WindowNamedPropertiesHandler::getOwnProp nsGlobalWindowInner* win = xpc::WindowOrNull(global); if (win->Length() > 0) { nsCOMPtr<nsPIDOMWindowOuter> childWin = win->GetChildWindow(str); if (childWin && ShouldExposeChildWindow(str, childWin)) { // We found a subframe of the right name. Shadowing via |var foo| in // global scope is still allowed, since |var| only looks up |own| // properties. But unqualified shadowing will fail, per-spec. JS::Rooted<JS::Value> v(aCx); - if (!WrapObject(aCx, childWin, &v)) { + if (!ToJSValue(aCx, nsGlobalWindowOuter::Cast(childWin), &v)) { return false; } FillPropertyDescriptor(aDesc, aProxy, 0, v); return true; } } // The rest of this function is for HTML documents only. nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(win->GetExtantDoc()); if (!htmlDoc) { return true; } nsHTMLDocument* document = static_cast<nsHTMLDocument*>(htmlDoc.get()); + JS::Rooted<JS::Value> v(aCx); Element* element = document->GetElementById(str); if (element) { - JS::Rooted<JS::Value> v(aCx); - if (!WrapObject(aCx, element, &v)) { + if (!ToJSValue(aCx, element, &v)) { return false; } FillPropertyDescriptor(aDesc, aProxy, 0, v); return true; } - nsWrapperCache* cache; - nsISupports* result = document->ResolveName(str, &cache); - if (!result) { - return true; + ErrorResult rv; + bool found = document->ResolveName(aCx, str, &v, rv); + if (rv.MaybeSetPendingException(aCx)) { + return false; } - JS::Rooted<JS::Value> v(aCx); - if (!WrapObject(aCx, result, cache, nullptr, &v)) { - return false; + if (found) { + FillPropertyDescriptor(aDesc, aProxy, 0, v); } - FillPropertyDescriptor(aDesc, aProxy, 0, v); return true; } bool WindowNamedPropertiesHandler::defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy, JS::Handle<jsid> aId, JS::Handle<JS::PropertyDescriptor> aDesc,
--- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -75,17 +75,16 @@ EXPORTS += [ 'nsIContent.h', 'nsIContentInlines.h', 'nsIContentIterator.h', 'nsIContentSerializer.h', 'nsIdentifierMapEntry.h', 'nsIDocument.h', 'nsIDocumentInlines.h', 'nsIDocumentObserver.h', - 'nsIDOMClassInfo.h', 'nsIGlobalObject.h', 'nsImageLoadingContent.h', 'nsIMutationObserver.h', 'nsINode.h', 'nsINodeList.h', 'nsIScriptContext.h', 'nsIScriptGlobalObject.h', 'nsIScriptObjectPrincipal.h',
--- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -2843,19 +2843,17 @@ struct InterfaceShimEntry { // We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each // interface that has interface constants that sites might be getting off // of Ci. const InterfaceShimEntry kInterfaceShimMap[] = { { "nsIXMLHttpRequest", "XMLHttpRequest" }, { "nsIDOMDOMException", "DOMException" }, { "nsIDOMNode", "Node" }, - { "nsIDOMCSSPrimitiveValue", "CSSPrimitiveValue" }, { "nsIDOMCSSRule", "CSSRule" }, - { "nsIDOMCSSValue", "CSSValue" }, { "nsIDOMEvent", "Event" }, { "nsIDOMNSEvent", "Event" }, { "nsIDOMKeyEvent", "KeyEvent" }, { "nsIDOMMouseEvent", "MouseEvent" }, { "nsIDOMMouseScrollEvent", "MouseScrollEvent" }, { "nsIDOMMutationEvent", "MutationEvent" }, { "nsIDOMUIEvent", "UIEvent" }, { "nsIDOMHTMLMediaElement", "HTMLMediaElement" },
deleted file mode 100644 --- a/dom/base/nsIDOMClassInfo.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. */ - -#ifndef nsIDOMClassInfo_h___ -#define nsIDOMClassInfo_h___ - -#include "nsIXPCScriptable.h" - -#define DOM_BASE_SCRIPTABLE_FLAGS \ - (XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \ - XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY | \ - XPC_SCRIPTABLE_ALLOW_PROP_MODS_TO_PROTOTYPE | \ - XPC_SCRIPTABLE_DONT_ASK_INSTANCE_FOR_SCRIPTABLE | \ - XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES) - -#define DEFAULT_SCRIPTABLE_FLAGS \ - (DOM_BASE_SCRIPTABLE_FLAGS | \ - XPC_SCRIPTABLE_WANT_RESOLVE | \ - XPC_SCRIPTABLE_WANT_PRECREATE) - -#define DOM_DEFAULT_SCRIPTABLE_FLAGS \ - (DEFAULT_SCRIPTABLE_FLAGS | \ - XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE | \ - XPC_SCRIPTABLE_CLASSINFO_INTERFACES_ONLY) - -#endif /* nsIDOMClassInfo_h___ */
--- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h @@ -2135,22 +2135,16 @@ inline nsINode* NODE_FROM(C& aContent, D NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID) inline nsISupports* ToSupports(nsINode* aPointer) { return aPointer; } -inline nsISupports* -ToCanonicalSupports(nsINode* aPointer) -{ - return aPointer; -} - // Some checks are faster to do on nsIContent or Element than on // nsINode, so spit out FromNode versions taking those types too. #define NS_IMPL_FROMNODE_GENERIC(_class, _check, _const) \ template<typename T> \ static auto FromNode(_const T& aNode) \ -> decltype(static_cast<_const _class*>(&aNode)) \ { \ return aNode._check ? static_cast<_const _class*>(&aNode) : nullptr; \
--- a/dom/base/nsRange.h +++ b/dom/base/nsRange.h @@ -582,20 +582,14 @@ protected: bool mIsPositioned : 1; bool mMaySpanAnonymousSubtrees : 1; bool mIsGenerated : 1; bool mCalledByJS : 1; }; inline nsISupports* -ToCanonicalSupports(nsRange* aRange) -{ - return static_cast<nsIDOMRange*>(aRange); -} - -inline nsISupports* ToSupports(nsRange* aRange) { return static_cast<nsIDOMRange*>(aRange); } #endif /* nsRange_h___ */
--- a/dom/battery/BatteryManager.cpp +++ b/dom/battery/BatteryManager.cpp @@ -8,17 +8,16 @@ #include <limits> #include "BatteryManager.h" #include "Constants.h" #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/Hal.h" #include "mozilla/dom/BatteryManagerBinding.h" #include "mozilla/Preferences.h" #include "nsContentUtils.h" -#include "nsIDOMClassInfo.h" #include "nsIDocument.h" /** * We have to use macros here because our leak analysis tool things we are * leaking strings when we have |static const nsString|. Sad :( */ #define LEVELCHANGE_EVENT_NAME NS_LITERAL_STRING("levelchange") #define CHARGINGCHANGE_EVENT_NAME NS_LITERAL_STRING("chargingchange")
--- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -30,17 +30,17 @@ #include "mozilla/Likely.h" #include "mozilla/MemoryReporting.h" #include "nsAutoPtr.h" #include "nsIDocument.h" #include "nsIGlobalObject.h" #include "nsIXPConnect.h" #include "nsJSUtils.h" #include "nsISupportsImpl.h" -#include "qsObjectHelper.h" +#include "xpcObjectHelper.h" #include "xpcpublic.h" #include "nsIVariant.h" #include "mozilla/dom/FakeString.h" #include "nsWrapperCacheInlines.h" class nsGenericHTMLElement; class nsIJSID; @@ -1319,17 +1319,17 @@ template <class T> MOZ_ALWAYS_INLINE bool HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope, T* value, JS::MutableHandle<JS::Value> rval) { if (JS_IsExceptionPending(cx)) { return false; } - qsObjectHelper helper(value, GetWrapperCache(value)); + xpcObjectHelper helper(value, GetWrapperCache(value)); return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval, helper, nullptr, true); } // Helper for calling HandleNewBindingWrappingFailure with smart pointers // (nsAutoPtr/nsRefPtr/nsCOMPtr) or references. template <class T, bool isSmartPtr=IsSmartPtr<T>::value> @@ -1553,17 +1553,17 @@ VariantToJsval(JSContext* aCx, nsIVarian // the nsWrapperCache for "p". template<class T> inline bool WrapObject(JSContext* cx, T* p, nsWrapperCache* cache, const nsIID* iid, JS::MutableHandle<JS::Value> rval) { if (xpc_FastGetCachedWrapper(cx, cache, rval)) return true; - qsObjectHelper helper(p, cache); + xpcObjectHelper helper(ToSupports(p), cache); JS::Rooted<JSObject*> scope(cx, JS::CurrentGlobalOrNull(cx)); return XPCOMObjectToJsval(cx, scope, helper, iid, true, rval); } // A specialization of the above for nsIVariant, because that needs to // do something different. template<> inline bool @@ -1653,17 +1653,17 @@ WrapObject(JSContext* cx, JSObject& p, J // Given an object "p" that inherits from nsISupports, wrap it and return the // result. Null is returned on wrapping failure. This is somewhat similar to // WrapObject() above, but does NOT allow Xrays around the result, since we // don't want those for our parent object. template<typename T> static inline JSObject* WrapNativeISupports(JSContext* cx, T* p, nsWrapperCache* cache) { - qsObjectHelper helper(ToSupports(p), cache); + xpcObjectHelper helper(ToSupports(p), cache); JS::Rooted<JSObject*> scope(cx, JS::CurrentGlobalOrNull(cx)); JS::Rooted<JS::Value> v(cx); return XPCOMObjectToJsval(cx, scope, helper, nullptr, false, &v) ? v.toObjectOrNull() : nullptr; }
--- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -187,20 +187,16 @@ DOMInterfaces = { 'concrete': False, 'nativeType': 'mozilla::css::GroupRule', }, 'CSSLexer': { 'wrapperCache': False }, -'CSSPrimitiveValue': { - 'nativeType': 'nsROCSSPrimitiveValue', -}, - 'CSSRule': { 'concrete': False, 'nativeType': 'mozilla::css::Rule' }, 'CSSStyleDeclaration': { 'nativeType': 'nsICSSDeclaration' }, @@ -209,24 +205,16 @@ DOMInterfaces = { 'nativeType': 'mozilla::BindingStyleRule', }, 'CSSStyleSheet': { 'nativeType': 'mozilla::StyleSheet', 'binaryNames': { 'ownerRule': 'DOMOwnerRule' }, }, -'CSSValue': { - 'concrete': False -}, - -'CSSValueList': { - 'nativeType': 'nsDOMCSSValueList' -}, - 'DedicatedWorkerGlobalScope': { 'headerFile': 'mozilla/dom/WorkerScope.h', }, 'DeviceAcceleration': { 'headerFile': 'mozilla/dom/DeviceMotionEvent.h', }, @@ -713,38 +701,30 @@ DOMInterfaces = { 'Range': { 'nativeType': 'nsRange', 'binaryNames': { '__stringifier': 'ToString' } }, -'Rect': { - 'nativeType': 'nsDOMCSSRect', -}, - 'Request': { 'binaryNames': { 'headers': 'headers_', 'referrerPolicy': 'referrerPolicy_' }, 'implicitJSContext': [ 'arrayBuffer', 'blob', 'formData', 'json', 'text' ], }, 'Response': { 'binaryNames': { 'headers': 'headers_' }, 'implicitJSContext': [ 'arrayBuffer', 'blob', 'formData', 'json', 'text', 'clone', 'cloneUnfiltered' ], }, -'RGBColor': { - 'nativeType': 'nsDOMCSSRGBColor', -}, - 'RTCDataChannel': { 'nativeType': 'nsDOMDataChannel', }, 'Screen': { 'nativeType': 'nsScreen', },
--- a/dom/bindings/ToJSValue.h +++ b/dom/bindings/ToJSValue.h @@ -182,17 +182,17 @@ typename EnableIf<!IsBaseOf<nsWrapperCac IsBaseOf<nsISupports, T>::value, bool>::Type ToJSValue(JSContext* aCx, T& aArgument, JS::MutableHandle<JS::Value> aValue) { // Make sure we're called in a compartment MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx)); - qsObjectHelper helper(ToSupports(&aArgument), nullptr); + xpcObjectHelper helper(ToSupports(&aArgument)); JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx)); return XPCOMObjectToJsval(aCx, scope, helper, nullptr, true, aValue); } // Accept nsRefPtr/nsCOMPtr template <typename T> MOZ_MUST_USE bool ToJSValue(JSContext* aCx,
--- a/dom/clients/manager/ClientHandle.cpp +++ b/dom/clients/manager/ClientHandle.cpp @@ -44,24 +44,26 @@ ClientHandle::StartOp(const ClientOpCons { // Hold a ref to the client until the remote operation completes. Otherwise // the ClientHandle might get de-refed and teardown the actor before we // get an answer. RefPtr<ClientHandle> kungFuGrip = this; MaybeExecute([aArgs, kungFuGrip, aRejectCallback, resolve = Move(aResolveCallback)] (ClientHandleChild* aActor) { + MOZ_RELEASE_ASSERT(aActor); ClientHandleOpChild* actor = new ClientHandleOpChild(kungFuGrip, aArgs, Move(resolve), Move(aRejectCallback)); if (!aActor->SendPClientHandleOpConstructor(actor, aArgs)) { // Constructor failure will call reject callback via ActorDestroy() return; } }, [aRejectCallback] { + MOZ_RELEASE_ASSERT(aRejectCallback); aRejectCallback(NS_ERROR_DOM_INVALID_STATE_ERR); }); } void ClientHandle::OnShutdownThing() { NS_ASSERT_OWNINGTHREAD(ClientHandle);
--- a/dom/clients/manager/ClientHandleOpChild.cpp +++ b/dom/clients/manager/ClientHandleOpChild.cpp @@ -34,15 +34,15 @@ ClientHandleOpChild::Recv__delete__(cons ClientHandleOpChild::ClientHandleOpChild(ClientHandle* aClientHandle, const ClientOpConstructorArgs& aArgs, const ClientOpCallback&& aResolveCallback, const ClientOpCallback&& aRejectCallback) : mClientHandle(aClientHandle) , mResolveCallback(Move(aResolveCallback)) , mRejectCallback(Move(aRejectCallback)) { - MOZ_DIAGNOSTIC_ASSERT(mClientHandle); - MOZ_DIAGNOSTIC_ASSERT(mResolveCallback); - MOZ_DIAGNOSTIC_ASSERT(mRejectCallback); + MOZ_RELEASE_ASSERT(mClientHandle); + MOZ_RELEASE_ASSERT(mResolveCallback); + MOZ_RELEASE_ASSERT(mRejectCallback); } } // namespace dom } // namespace mozilla
--- a/dom/clients/manager/ClientManager.cpp +++ b/dom/clients/manager/ClientManager.cpp @@ -22,18 +22,23 @@ namespace mozilla { namespace dom { using mozilla::ipc::BackgroundChild; using mozilla::ipc::PBackgroundChild; using mozilla::ipc::PrincipalInfo; namespace { -uint32_t kBadThreadLocalIndex = -1; +const uint32_t kBadThreadLocalIndex = -1; +const uint32_t kThreadLocalMagic1 = 0x8d57eea6; +const uint32_t kThreadLocalMagic2 = 0x59f375c9; +uint32_t sClientManagerThreadLocalMagic1 = kThreadLocalMagic1; uint32_t sClientManagerThreadLocalIndex = kBadThreadLocalIndex; +uint32_t sClientManagerThreadLocalMagic2 = kThreadLocalMagic2; +uint32_t sClientManagerThreadLocalIndexDuplicate = kBadThreadLocalIndex; } // anonymous namespace ClientManager::ClientManager() { PBackgroundChild* parentActor = BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!parentActor)) { Shutdown(); @@ -74,17 +79,21 @@ ClientManager::ClientManager() } ClientManager::~ClientManager() { NS_ASSERT_OWNINGTHREAD(ClientManager); Shutdown(); - MOZ_DIAGNOSTIC_ASSERT(this == PR_GetThreadPrivate(sClientManagerThreadLocalIndex)); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate); + MOZ_RELEASE_ASSERT(this == PR_GetThreadPrivate(sClientManagerThreadLocalIndex)); #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED PRStatus status = #endif PR_SetThreadPrivate(sClientManagerThreadLocalIndex, nullptr); MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS); } @@ -180,53 +189,65 @@ ClientManager::StartOp(const ClientOpCon RefPtr<ClientOpPromise> ref = promise.get(); return ref.forget(); } // static already_AddRefed<ClientManager> ClientManager::GetOrCreateForCurrentThread() { - MOZ_DIAGNOSTIC_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate); RefPtr<ClientManager> cm = static_cast<ClientManager*>(PR_GetThreadPrivate(sClientManagerThreadLocalIndex)); if (!cm) { cm = new ClientManager(); #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED PRStatus status = #endif PR_SetThreadPrivate(sClientManagerThreadLocalIndex, cm.get()); MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS); } - MOZ_ASSERT(cm); + MOZ_RELEASE_ASSERT(cm); return cm.forget(); } WorkerPrivate* ClientManager::GetWorkerPrivate() const { NS_ASSERT_OWNINGTHREAD(ClientManager); MOZ_DIAGNOSTIC_ASSERT(GetActor()); return GetActor()->GetWorkerPrivate(); } // static void ClientManager::Startup() { MOZ_ASSERT(NS_IsMainThread()); + + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == kBadThreadLocalIndex); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate); + #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED PRStatus status = #endif PR_NewThreadPrivateIndex(&sClientManagerThreadLocalIndex, nullptr); MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS); + MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex); + sClientManagerThreadLocalIndexDuplicate = sClientManagerThreadLocalIndex; + ClientPrefsInit(); } // static UniquePtr<ClientSource> ClientManager::CreateSource(ClientType aType, nsISerialEventTarget* aEventTarget, nsIPrincipal* aPrincipal) {
--- a/dom/clients/manager/ClientThing.h +++ b/dom/clients/manager/ClientThing.h @@ -12,77 +12,99 @@ namespace mozilla { namespace dom { // Base class representing various Client "things" such as ClientHandle, // ClientSource, and ClientManager. Currently it provides a common set // of code for handling activation and shutdown of IPC actors. template <typename ActorType> class ClientThing { + static const uint32_t kMagic1 = 0xC9FE2C9C; + static const uint32_t kMagic2 = 0x832072D4; + ActorType* mActor; + uint32_t mMagic1; + uint32_t mMagic2; bool mShutdown; protected: ClientThing() : mActor(nullptr) + , mMagic1(kMagic1) + , mMagic2(kMagic2) , mShutdown(false) { } ~ClientThing() { + AssertIsValid(); ShutdownThing(); + mMagic1 = 0; + mMagic2 = 0; + } + + void + AssertIsValid() const + { + MOZ_RELEASE_ASSERT(mMagic1 == kMagic1); + MOZ_RELEASE_ASSERT(mMagic2 == kMagic2); } // Return the current actor. ActorType* GetActor() const { + AssertIsValid(); return mActor; } // Returns true if ShutdownThing() has been called. bool IsShutdown() const { + AssertIsValid(); return mShutdown; } // Conditionally execute the given callable based on the current state. template<typename Callable> void MaybeExecute(const Callable& aSuccess, const std::function<void()>& aFailure = []{}) { + AssertIsValid(); if (mShutdown) { aFailure(); return; } MOZ_DIAGNOSTIC_ASSERT(mActor); aSuccess(mActor); } // Attach activate the thing by attaching its underlying IPC actor. This // will make the thing register as the actor's owner as well. The actor // must call RevokeActor() to clear this weak back reference before its // destroyed. void ActivateThing(ActorType* aActor) { + AssertIsValid(); MOZ_DIAGNOSTIC_ASSERT(aActor); MOZ_DIAGNOSTIC_ASSERT(!mActor); MOZ_DIAGNOSTIC_ASSERT(!mShutdown); mActor = aActor; mActor->SetOwner(this); } // Start destroying the underlying actor and disconnect the thing. void ShutdownThing() { + AssertIsValid(); if (mShutdown) { return; } mShutdown = true; // If we are shutdown before the actor, then clear the weak references // between the actor and the thing. if (mActor) { @@ -101,16 +123,17 @@ protected: // by default do nothing } public: // Clear the weak references between the thing and its IPC actor. void RevokeActor(ActorType* aActor) { + AssertIsValid(); MOZ_DIAGNOSTIC_ASSERT(mActor); MOZ_DIAGNOSTIC_ASSERT(mActor == aActor); mActor->RevokeOwner(this); mActor = nullptr; // Also consider the ClientThing shutdown. We simply set the flag // instead of calling ShutdownThing() to avoid calling MaybeStartTeardown() // on the destroyed actor.
--- a/dom/console/Console.cpp +++ b/dom/console/Console.cpp @@ -89,18 +89,18 @@ class ConsoleCallData final public: NS_INLINE_DECL_REFCOUNTING(ConsoleCallData) ConsoleCallData() : mMethodName(Console::MethodLog) , mTimeStamp(JS_Now() / PR_USEC_PER_MSEC) , mStartTimerValue(0) , mStartTimerStatus(Console::eTimerUnknown) - , mStopTimerDuration(0) - , mStopTimerStatus(Console::eTimerUnknown) + , mLogTimerDuration(0) + , mLogTimerStatus(Console::eTimerUnknown) , mCountValue(MAX_PAGE_COUNTERS) , mIDType(eUnknown) , mOuterIDNumber(0) , mInnerIDNumber(0) , mStatus(eUnused) {} bool @@ -216,24 +216,24 @@ public: // They will be set on the owning thread and never touched again on that // thread. They will be used in order to create a ConsoleTimerStart dictionary // when console.time() is used. DOMHighResTimeStamp mStartTimerValue; nsString mStartTimerLabel; Console::TimerStatus mStartTimerStatus; // These values are set in the owning thread and they contain the duration, - // the name and the status of the StopTimer method. If status is false, + // the name and the status of the LogTimer method. If status is false, // something went wrong. They will be set on the owning thread and never // touched again on that thread. They will be used in order to create a - // ConsoleTimerEnd dictionary. This members are set when - // console.timeEnd() is called. - double mStopTimerDuration; - nsString mStopTimerLabel; - Console::TimerStatus mStopTimerStatus; + // ConsoleTimerLogOrEnd dictionary. This members are set when + // console.timeEnd() or console.timeLog() are called. + double mLogTimerDuration; + nsString mLogTimerLabel; + Console::TimerStatus mLogTimerStatus; // These 2 values are set by IncreaseCounter on the owning thread and they are // used CreateCounterValue. These members are set when console.count() is // called. nsString mCountLabel; uint32_t mCountValue; // The concept of outerID and innerID is misleading because when a @@ -1226,40 +1226,52 @@ Console::GroupEnd(const GlobalObject& aG { const Sequence<JS::Value> data; Method(aGlobal, MethodGroupEnd, NS_LITERAL_STRING("groupEnd"), data); } /* static */ void Console::Time(const GlobalObject& aGlobal, const nsAString& aLabel) { - StringMethod(aGlobal, aLabel, MethodTime, NS_LITERAL_STRING("time")); + StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodTime, + NS_LITERAL_STRING("time")); } /* static */ void Console::TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel) { - StringMethod(aGlobal, aLabel, MethodTimeEnd, NS_LITERAL_STRING("timeEnd")); + StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodTimeEnd, + NS_LITERAL_STRING("timeEnd")); +} + +/* static */ void +Console::TimeLog(const GlobalObject& aGlobal, const nsAString& aLabel, + const Sequence<JS::Value>& aData) +{ + StringMethod(aGlobal, aLabel, aData, MethodTimeLog, + NS_LITERAL_STRING("timeLog")); } /* static */ void Console::StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel, - MethodName aMethodName, const nsAString& aMethodString) + const Sequence<JS::Value>& aData, MethodName aMethodName, + const nsAString& aMethodString) { RefPtr<Console> console = GetConsole(aGlobal); if (!console) { return; } - console->StringMethodInternal(aGlobal.Context(), aLabel, aMethodName, + console->StringMethodInternal(aGlobal.Context(), aLabel, aData, aMethodName, aMethodString); } void Console::StringMethodInternal(JSContext* aCx, const nsAString& aLabel, + const Sequence<JS::Value>& aData, MethodName aMethodName, const nsAString& aMethodString) { ConsoleCommon::ClearException ce(aCx); Sequence<JS::Value> data; SequenceRooter<JS::Value> rooter(aCx, &data); @@ -1267,16 +1279,22 @@ Console::StringMethodInternal(JSContext* if (!dom::ToJSValue(aCx, aLabel, &value)) { return; } if (!data.AppendElement(value, fallible)) { return; } + for (uint32_t i = 0; i < aData.Length(); ++i) { + if (!data.AppendElement(aData[i], fallible)) { + return; + } + } + MethodInternal(aCx, aMethodName, aMethodString, data); } /* static */ void Console::TimeStamp(const GlobalObject& aGlobal, const JS::Handle<JS::Value> aData) { JSContext* cx = aGlobal.Context(); @@ -1417,17 +1435,18 @@ Console::Assert(const GlobalObject& aGlo if (!aCondition) { Method(aGlobal, MethodAssert, NS_LITERAL_STRING("assert"), aData); } } /* static */ void Console::Count(const GlobalObject& aGlobal, const nsAString& aLabel) { - StringMethod(aGlobal, aLabel, MethodCount, NS_LITERAL_STRING("count")); + StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodCount, + NS_LITERAL_STRING("count")); } namespace { void StackFrameToStackEntry(JSContext* aCx, nsIStackFrame* aStackFrame, ConsoleStackEntry& aStackEntry) { @@ -1568,36 +1587,46 @@ Console::MethodInternal(JSContext* aCx, // nsIStackFrame is not threadsafe, so we need to snapshot it now, // before we post our runnable to the main thread. callData->mReifiedStack.emplace(); ReifyStack(aCx, stack, *callData->mReifiedStack); } DOMHighResTimeStamp monotonicTimer; - // Monotonic timer for 'time' and 'timeEnd' + // Monotonic timer for 'time', 'timeLog' and 'timeEnd' if ((aMethodName == MethodTime || + aMethodName == MethodTimeLog || aMethodName == MethodTimeEnd || aMethodName == MethodTimeStamp) && !MonotonicTimer(aCx, aMethodName, aData, &monotonicTimer)) { return; } if (aMethodName == MethodTime && !aData.IsEmpty()) { callData->mStartTimerStatus = StartTimer(aCx, aData[0], monotonicTimer, callData->mStartTimerLabel, &callData->mStartTimerValue); } else if (aMethodName == MethodTimeEnd && !aData.IsEmpty()) { - callData->mStopTimerStatus = StopTimer(aCx, aData[0], - monotonicTimer, - callData->mStopTimerLabel, - &callData->mStopTimerDuration); + callData->mLogTimerStatus = LogTimer(aCx, aData[0], + monotonicTimer, + callData->mLogTimerLabel, + &callData->mLogTimerDuration, + true /* Cancel timer */); + } + + else if (aMethodName == MethodTimeLog && !aData.IsEmpty()) { + callData->mLogTimerStatus = LogTimer(aCx, aData[0], + monotonicTimer, + callData->mLogTimerLabel, + &callData->mLogTimerDuration, + false /* Cancel timer */); } else if (aMethodName == MethodCount) { callData->mCountValue = IncreaseCounter(aCx, aData, callData->mCountLabel); if (!callData->mCountValue) { return; } } @@ -1858,20 +1887,21 @@ Console::PopulateConsoleNotificationInTh } } else if (aData->mMethodName == MethodTime && !aArguments.IsEmpty()) { event.mTimer = CreateStartTimerValue(aCx, aData->mStartTimerLabel, aData->mStartTimerStatus); } - else if (aData->mMethodName == MethodTimeEnd && !aArguments.IsEmpty()) { - event.mTimer = CreateStopTimerValue(aCx, aData->mStopTimerLabel, - aData->mStopTimerDuration, - aData->mStopTimerStatus); + else if ((aData->mMethodName == MethodTimeEnd || + aData->mMethodName == MethodTimeLog) && !aArguments.IsEmpty()) { + event.mTimer = CreateLogOrEndTimerValue(aCx, aData->mLogTimerLabel, + aData->mLogTimerDuration, + aData->mLogTimerStatus); } else if (aData->mMethodName == MethodCount) { event.mCounter = CreateCounterValue(aCx, aData->mCountLabel, aData->mCountValue); } JSAutoCompartment ac2(aCx, targetScope); @@ -2316,20 +2346,21 @@ Console::CreateStartTimerValue(JSContext if (!ToJSValue(aCx, timer, &value)) { return JS::UndefinedValue(); } return value; } Console::TimerStatus -Console::StopTimer(JSContext* aCx, const JS::Value& aName, - DOMHighResTimeStamp aTimestamp, - nsAString& aTimerLabel, - double* aTimerDuration) +Console::LogTimer(JSContext* aCx, const JS::Value& aName, + DOMHighResTimeStamp aTimestamp, + nsAString& aTimerLabel, + double* aTimerDuration, + bool aCancelTimer) { AssertIsOnOwningThread(); MOZ_ASSERT(aTimerDuration); *aTimerDuration = 0; JS::Rooted<JS::Value> name(aCx, aName); JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, name)); @@ -2340,34 +2371,42 @@ Console::StopTimer(JSContext* aCx, const nsAutoJSString key; if (NS_WARN_IF(!key.init(aCx, jsString))) { return eTimerJSException; } aTimerLabel = key; DOMHighResTimeStamp value = 0; - if (!mTimerRegistry.Remove(key, &value)) { - NS_WARNING("mTimerRegistry entry not found"); - return eTimerDoesntExist; + + if (aCancelTimer) { + if (!mTimerRegistry.Remove(key, &value)) { + NS_WARNING("mTimerRegistry entry not found"); + return eTimerDoesntExist; + } + } else { + if (!mTimerRegistry.Get(key, &value)) { + NS_WARNING("mTimerRegistry entry not found"); + return eTimerDoesntExist; + } } *aTimerDuration = aTimestamp - value; return eTimerDone; } JS::Value -Console::CreateStopTimerValue(JSContext* aCx, const nsAString& aLabel, - double aDuration, TimerStatus aStatus) const +Console::CreateLogOrEndTimerValue(JSContext* aCx, const nsAString& aLabel, + double aDuration, TimerStatus aStatus) const { if (aStatus != eTimerDone) { return CreateTimerError(aCx, aLabel, aStatus); } - RootedDictionary<ConsoleTimerEnd> timer(aCx); + RootedDictionary<ConsoleTimerLogOrEnd> timer(aCx); timer.mName = aLabel; timer.mDuration = aDuration; JS::Rooted<JS::Value> value(aCx); if (!ToJSValue(aCx, timer, &value)) { return JS::UndefinedValue(); } @@ -2991,16 +3030,17 @@ Console::WebIDLLogLevelToInteger(Console { switch (aLevel) { case ConsoleLogLevel::All: return 0; case ConsoleLogLevel::Debug: return 2; case ConsoleLogLevel::Log: return 3; case ConsoleLogLevel::Info: return 3; case ConsoleLogLevel::Clear: return 3; case ConsoleLogLevel::Trace: return 3; + case ConsoleLogLevel::TimeLog: return 3; case ConsoleLogLevel::TimeEnd: return 3; case ConsoleLogLevel::Time: return 3; case ConsoleLogLevel::Group: return 3; case ConsoleLogLevel::GroupEnd: return 3; case ConsoleLogLevel::Profile: return 3; case ConsoleLogLevel::ProfileEnd: return 3; case ConsoleLogLevel::Dir: return 3; case ConsoleLogLevel::Dirxml: return 3; @@ -3028,16 +3068,17 @@ Console::InternalLogLevelToInteger(Metho case MethodTable: return 3; case MethodTrace: return 3; case MethodDir: return 3; case MethodDirxml: return 3; case MethodGroup: return 3; case MethodGroupCollapsed: return 3; case MethodGroupEnd: return 3; case MethodTime: return 3; + case MethodTimeLog: return 3; case MethodTimeEnd: return 3; case MethodTimeStamp: return 3; case MethodAssert: return 3; case MethodCount: return 3; case MethodClear: return 3; case MethodProfile: return 3; case MethodProfileEnd: return 3; default:
--- a/dom/console/Console.h +++ b/dom/console/Console.h @@ -92,16 +92,20 @@ public: static void GroupEnd(const GlobalObject& aGlobal); static void Time(const GlobalObject& aGlobal, const nsAString& aLabel); static void + TimeLog(const GlobalObject& aGlobal, const nsAString& aLabel, + const Sequence<JS::Value>& aData); + + static void TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel); static void TimeStamp(const GlobalObject& aGlobal, const JS::Handle<JS::Value> aData); static void Profile(const GlobalObject& aGlobal, const Sequence<JS::Value>& aData); @@ -154,16 +158,17 @@ private: MethodTable, MethodTrace, MethodDir, MethodDirxml, MethodGroup, MethodGroupCollapsed, MethodGroupEnd, MethodTime, + MethodTimeLog, MethodTimeEnd, MethodTimeStamp, MethodAssert, MethodCount, MethodClear, MethodProfile, MethodProfileEnd, }; @@ -188,20 +193,22 @@ private: const nsAString& aString, const Sequence<JS::Value>& aData); void MethodInternal(JSContext* aCx, MethodName aName, const nsAString& aString, const Sequence<JS::Value>& aData); static void StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel, - MethodName aMethodName, const nsAString& aMethodString); + const Sequence<JS::Value>& aData, MethodName aMethodName, + const nsAString& aMethodString); void StringMethodInternal(JSContext* aCx, const nsAString& aLabel, + const Sequence<JS::Value>& aData, MethodName aMethodName, const nsAString& aMethodString); // This method must receive aCx and aArguments in the same JSCompartment. void ProcessCallData(JSContext* aCx, ConsoleCallData* aData, const Sequence<JS::Value>& aArguments); @@ -312,43 +319,45 @@ private: // thread. // * aCx - this is the context that will root the returned value. // * aTimerLabel - this label must be what StartTimer received as aTimerLabel. // * aTimerStatus - the return value of StartTimer. JS::Value CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel, TimerStatus aTimerStatus) const; - // StopTimer follows the same pattern as StartTimer: it runs on the + // LogTimer follows the same pattern as StartTimer: it runs on the // owning thread and populates aTimerLabel and aTimerDuration, used by - // CreateStopTimerValue. + // CreateLogOrEndTimerValue. // * aCx - the JSContext rooting aName. // * aName - this is (should be) the name of the timer as JS::Value. // * aTimestamp - the monotonicTimer for this context taken from // performance.now(). // * aTimerLabel - This label will be populated with the aName converted to a // string. // * aTimerDuration - the difference between aTimestamp and when the timer // started (see StartTimer). + // * aCancelTimer - if true, the timer is removed from the table. TimerStatus - StopTimer(JSContext* aCx, const JS::Value& aName, - DOMHighResTimeStamp aTimestamp, - nsAString& aTimerLabel, - double* aTimerDuration); + LogTimer(JSContext* aCx, const JS::Value& aName, + DOMHighResTimeStamp aTimestamp, + nsAString& aTimerLabel, + double* aTimerDuration, + bool aCancelTimer); // This method generates a ConsoleTimerEnd dictionary exposed as JS::Value, or - // a ConsoleTimerError dictionary if aTimerStatus is false. See StopTimer. + // a ConsoleTimerError dictionary if aTimerStatus is false. See LogTimer. // * aCx - this is the context that will root the returned value. - // * aTimerLabel - this label must be what StopTimer received as aTimerLabel. - // * aTimerDuration - this is what StopTimer received as aTimerDuration - // * aTimerStatus - the return value of StopTimer. + // * aTimerLabel - this label must be what LogTimer received as aTimerLabel. + // * aTimerDuration - this is what LogTimer received as aTimerDuration + // * aTimerStatus - the return value of LogTimer. JS::Value - CreateStopTimerValue(JSContext* aCx, const nsAString& aTimerLabel, - double aTimerDuration, - TimerStatus aTimerStatus) const; + CreateLogOrEndTimerValue(JSContext* aCx, const nsAString& aTimerLabel, + double aTimerDuration, + TimerStatus aTimerStatus) const; // The method populates a Sequence from an array of JS::Value. bool ArgumentsToValueList(const Sequence<JS::Value>& aData, Sequence<JS::Value>& aSequence) const; // This method follows the same pattern as StartTimer: its runs on the owning // thread and populate aCountLabel, used by CreateCounterValue. Returns
--- a/dom/console/ConsoleInstance.cpp +++ b/dom/console/ConsoleInstance.cpp @@ -142,24 +142,34 @@ ConsoleInstance::GroupEnd(JSContext* aCx const Sequence<JS::Value> data; mConsole->MethodInternal(aCx, Console::MethodGroupEnd, NS_LITERAL_STRING("groupEnd"), data); } void ConsoleInstance::Time(JSContext* aCx, const nsAString& aLabel) { - mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTime, + mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(), + Console::MethodTime, NS_LITERAL_STRING("time")); } void +ConsoleInstance::TimeLog(JSContext* aCx, const nsAString& aLabel, + const Sequence<JS::Value>& aData) +{ + mConsole->StringMethodInternal(aCx, aLabel, aData, Console::MethodTimeLog, + NS_LITERAL_STRING("timeLog")); +} + +void ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel) { - mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTimeEnd, + mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(), + Console::MethodTimeEnd, NS_LITERAL_STRING("timeEnd")); } void ConsoleInstance::TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData) { ConsoleCommon::ClearException ce(aCx); @@ -196,17 +206,18 @@ ConsoleInstance::Assert(JSContext* aCx, mConsole->MethodInternal(aCx, Console::MethodAssert, NS_LITERAL_STRING("assert"), aData); } } void ConsoleInstance::Count(JSContext* aCx, const nsAString& aLabel) { - mConsole->StringMethodInternal(aCx, aLabel, Console::MethodCount, + mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(), + Console::MethodCount, NS_LITERAL_STRING("count")); } void ConsoleInstance::Clear(JSContext* aCx) { const Sequence<JS::Value> data; mConsole->MethodInternal(aCx, Console::MethodClear,
--- a/dom/console/ConsoleInstance.h +++ b/dom/console/ConsoleInstance.h @@ -70,16 +70,20 @@ public: void GroupEnd(JSContext* aCx); void Time(JSContext* aCx, const nsAString& aLabel); void + TimeLog(JSContext* aCx, const nsAString& aLabel, + const Sequence<JS::Value>& aData); + + void TimeEnd(JSContext* aCx, const nsAString& aLabel); void TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData); void Profile(JSContext* aCx, const Sequence<JS::Value>& aData);
--- a/dom/console/tests/mochitest.ini +++ b/dom/console/tests/mochitest.ini @@ -5,8 +5,9 @@ support-files = [test_bug659625.html] [test_bug978522.html] [test_bug979109.html] [test_bug989665.html] [test_consoleEmptyStack.html] [test_console_binding.html] [test_console_proto.html] [test_devtools_pref.html] +[test_timer.html]
new file mode 100644 --- /dev/null +++ b/dom/console/tests/test_timer.html @@ -0,0 +1,111 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for timeStart/timeLog/timeEnd in console</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function ConsoleListener() { + SpecialPowers.addObserver(this, "console-api-log-event"); +} + +ConsoleListener.prototype = { + observe(aSubject, aTopic, aData) { + let obj = aSubject.wrappedJSObject; + if (obj.arguments[0] != 'test') { + return; + } + + if (!this._cb) { + ok(false, "Callback not set!"); + return; + } + + if (!this._cb(obj)) { + return; + } + + this._cb = null; + this._resolve(); + }, + + shutdown() { + SpecialPowers.removeObserver(this, "console-api-log-event"); + }, + + waitFor(cb) { + return new Promise(resolve => { + this._cb = cb; + this._resolve = resolve; + }); + }, +}; + +let listener = new ConsoleListener(); + +// Timer creation: +async function runTest() { + let cl = listener.waitFor(obj => { + return ("timer" in obj) && + ("name" in obj.timer) && + obj.timer.name == 'test'; + }); + + console.time('test'); + await cl; + ok(true, "Console.time received!"); + + // Timer check: + cl = listener.waitFor(obj => { + return ("timer" in obj) && + ("name" in obj.timer) && + obj.timer.name == 'test' && + ("duration" in obj.timer) && + obj.timer.duration > 0 && + obj.arguments[1] == 1 && + obj.arguments[2] == 2 && + obj.arguments[3] == 3 && + obj.arguments[4] == 4; + }); + console.timeLog('test', 1, 2, 3, 4); + await cl; + ok(true, "Console.timeLog received!"); + + // Time deleted: + cl = listener.waitFor(obj => { + return ("timer" in obj) && + ("name" in obj.timer) && + obj.timer.name == 'test' && + ("duration" in obj.timer) && + obj.timer.duration > 0; + }); + console.timeEnd('test'); + await cl; + ok(true, "Console.timeEnd received!"); + + // Here an error: + cl = listener.waitFor(obj => { + return ("timer" in obj) && + ("name" in obj.timer) && + obj.timer.name == 'test' && + ("error" in obj.timer); + }); + console.timeLog('test'); + await cl; + ok(true, "Console.time with error received!"); +} + +runTest().then(() => { + listener.shutdown(); + SimpleTest.finish(); +}); + + </script> +</body> +</html>
--- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -5364,16 +5364,64 @@ EventStateManager::ResetLastOverForConte if (aElemWrapper && aElemWrapper->mLastOverElement && nsContentUtils::ContentIsDescendantOf(aElemWrapper->mLastOverElement, aContent)) { aElemWrapper->mLastOverElement = nullptr; } } void +EventStateManager::RemoveNodeFromChainIfNeeded(EventStates aState, + nsIContent* aContentRemoved, + bool aNotify) +{ + MOZ_ASSERT(aState == NS_EVENT_STATE_HOVER || aState == NS_EVENT_STATE_ACTIVE); + if (!aContentRemoved->IsElement() || + !aContentRemoved->AsElement()->State().HasState(aState)) { + return; + } + + nsCOMPtr<nsIContent>& leaf = + aState == NS_EVENT_STATE_HOVER ? mHoverContent : mActiveContent; + + MOZ_ASSERT(leaf); + // XBL Likes to unbind content without notifying, thus the + // NODE_IS_ANONYMOUS_ROOT check... + MOZ_ASSERT(nsContentUtils::ContentIsFlattenedTreeDescendantOf( + leaf, aContentRemoved) || + leaf->SubtreeRoot()->HasFlag(NODE_IS_ANONYMOUS_ROOT)); + + nsIContent* newLeaf = aContentRemoved->GetFlattenedTreeParent(); + MOZ_ASSERT_IF(newLeaf, + newLeaf->IsElement() && + newLeaf->AsElement()->State().HasState(aState)); + if (aNotify) { + SetContentState(newLeaf, aState); + } else { + // We don't update the removed content's state here, since removing NAC + // happens from layout and we don't really want to notify at that point or + // what not. + // + // Also, NAC is not observable and NAC being removed will go away soon. + leaf = newLeaf; + } + MOZ_ASSERT(leaf == newLeaf); +} + +void +EventStateManager::NativeAnonymousContentRemoved(nsIContent* aContent) +{ + // FIXME(bug 1450250): <svg:use> is nasty. + MOZ_ASSERT(aContent->IsRootOfNativeAnonymousSubtree() || + aContent->GetParentNode()->IsSVGElement(nsGkAtoms::use)); + RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent, false); + RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent, false); +} + +void EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent) { /* * Anchor and area elements when focused or hovered might make the UI to show * the current link. We want to make sure that the UI gets informed when they * are actually removed from the DOM. */ if (aContent->IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area) && @@ -5387,29 +5435,18 @@ EventStateManager::ContentRemoved(nsIDoc IMEStateManager::OnRemoveContent(mPresContext, aContent); // inform the focus manager that the content is being removed. If this // content is focused, the focus will be removed without firing events. nsFocusManager* fm = nsFocusManager::GetFocusManager(); if (fm) fm->ContentRemoved(aDocument, aContent); - if (mHoverContent && - nsContentUtils::ContentIsFlattenedTreeDescendantOf(mHoverContent, aContent)) { - // Since hover is hierarchical, set the current hover to the - // content's parent node. - SetContentState(aContent->GetFlattenedTreeParent(), NS_EVENT_STATE_HOVER); - } - - if (mActiveContent && - nsContentUtils::ContentIsFlattenedTreeDescendantOf(mActiveContent, aContent)) { - // Active is hierarchical, so set the current active to the - // content's parent node. - SetContentState(aContent->GetFlattenedTreeParent(), NS_EVENT_STATE_ACTIVE); - } + RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent, true); + RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent, true); if (sDragOverContent && sDragOverContent->OwnerDoc() == aContent->OwnerDoc() && nsContentUtils::ContentIsFlattenedTreeDescendantOf(sDragOverContent, aContent)) { sDragOverContent = nullptr; } PointerEventHandler::ReleaseIfCaptureByDescendant(aContent);
--- a/dom/events/EventStateManager.h +++ b/dom/events/EventStateManager.h @@ -143,16 +143,18 @@ public: * @return Whether the content was able to change all states. Returns false * if a resulting DOM event causes the content node passed in * to not change states. Note, the frame for the content may * change as a result of the content state change, because of * frame reconstructions that may occur, but this does not * affect the return value. */ bool SetContentState(nsIContent* aContent, EventStates aState); + + void NativeAnonymousContentRemoved(nsIContent* aAnonContent); void ContentRemoved(nsIDocument* aDocument, nsIContent* aContent); bool EventStatusOK(WidgetGUIEvent* aEvent); /** * EventStateManager stores IMEContentObserver while it's observing contents. * Following mehtods are called by IMEContentObserver when it starts to * observe or stops observing the content. @@ -1082,16 +1084,24 @@ protected: bool HandleCrossProcessEvent(WidgetEvent* aEvent, nsEventStatus* aStatus); void ReleaseCurrentIMEContentObserver(); void HandleQueryContentEvent(WidgetQueryContentEvent* aEvent); private: + // Removes a node from the :hover / :active chain if needed, notifying if the + // node is not a NAC subtree. + // + // Only meant to be called from ContentRemoved and + // NativeAnonymousContentRemoved. + void RemoveNodeFromChainIfNeeded(EventStates aState, + nsIContent* aContentRemoved, + bool aNotify); bool IsEventOutsideDragThreshold(WidgetInputEvent* aEvent) const; static inline void DoStateChange(dom::Element* aElement, EventStates aState, bool aAddState); static inline void DoStateChange(nsIContent* aContent, EventStates aState, bool aAddState); static void UpdateAncestorState(nsIContent* aStartNode,
--- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -1341,21 +1341,9 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(TextArea) NS_DECLARE_NS_NEW_HTML_ELEMENT(Tfoot) NS_DECLARE_NS_NEW_HTML_ELEMENT(Thead) NS_DECLARE_NS_NEW_HTML_ELEMENT(Time) NS_DECLARE_NS_NEW_HTML_ELEMENT(Title) NS_DECLARE_NS_NEW_HTML_ELEMENT(Track) NS_DECLARE_NS_NEW_HTML_ELEMENT(Unknown) NS_DECLARE_NS_NEW_HTML_ELEMENT(Video) -inline nsISupports* -ToSupports(nsGenericHTMLElement* aHTMLElement) -{ - return static_cast<nsIContent*>(aHTMLElement); -} - -inline nsISupports* -ToCanonicalSupports(nsGenericHTMLElement* aHTMLElement) -{ - return static_cast<nsIContent*>(aHTMLElement); -} - #endif /* nsGenericHTMLElement_h___ */
--- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -1884,74 +1884,59 @@ nsHTMLDocument::CaptureEvents() } void nsHTMLDocument::ReleaseEvents() { WarnOnceAbout(nsIDocument::eUseOfReleaseEvents); } -nsISupports* -nsHTMLDocument::ResolveName(const nsAString& aName, nsWrapperCache **aCache) +bool +nsHTMLDocument::ResolveName(JSContext* aCx, const nsAString& aName, + JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError) { nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName); if (!entry) { - *aCache = nullptr; - return nullptr; + return false; } nsBaseContentList *list = entry->GetNameContentList(); uint32_t length = list ? list->Length() : 0; + nsIContent *node; if (length > 0) { - if (length == 1) { - // Only one element in the list, return the element instead of returning - // the list. - nsIContent *node = list->Item(0); - *aCache = node; - return node; + if (length > 1) { + // The list contains more than one element, return the whole list. + if (!ToJSValue(aCx, list, aRetval)) { + aError.NoteJSContextException(aCx); + return false; + } + return true; } - // The list contains more than one element, return the whole list. - *aCache = list; - return list; - } - - // No named items were found, see if there's one registerd by id for aName. - Element *e = entry->GetIdElement(); - - if (e && nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(e)) { - *aCache = e; - return e; + // Only one element in the list, return the element instead of returning + // the list. + node = list->Item(0); + } else { + // No named items were found, see if there's one registerd by id for aName. + Element *e = entry->GetIdElement(); + + if (!e || !nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(e)) { + return false; + } + + node = e; } - *aCache = nullptr; - return nullptr; -} - -void -nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound, - JS::MutableHandle<JSObject*> aRetval, - ErrorResult& rv) -{ - nsWrapperCache* cache; - nsISupports* supp = ResolveName(aName, &cache); - if (!supp) { - aFound = false; - aRetval.set(nullptr); - return; + if (!ToJSValue(aCx, node, aRetval)) { + aError.NoteJSContextException(aCx); + return false; } - JS::Rooted<JS::Value> val(cx); - if (!dom::WrapObject(cx, supp, cache, nullptr, &val)) { - rv.Throw(NS_ERROR_OUT_OF_MEMORY); - return; - } - aFound = true; - aRetval.set(&val.toObject()); + return true; } void nsHTMLDocument::GetSupportedNames(nsTArray<nsString>& aNames) { for (auto iter = mIdentifierMap.Iter(); !iter.Done(); iter.Next()) { nsIdentifierMapEntry* entry = iter.Get(); if (entry->HasNameElement() ||
--- a/dom/html/nsHTMLDocument.h +++ b/dom/html/nsHTMLDocument.h @@ -74,17 +74,19 @@ public: nsContentList* GetExistingForms() const { return mForms; } mozilla::dom::HTMLAllCollection* All(); - nsISupports* ResolveName(const nsAString& aName, nsWrapperCache **aCache); + // Returns whether an object was found for aName. + bool ResolveName(JSContext* aCx, const nsAString& aName, + JS::MutableHandle<JS::Value> aRetval, mozilla::ErrorResult& aError); virtual void AddedForm() override; virtual void RemovedForm() override; virtual int32_t GetNumFormsSynchronous() override; virtual void TearingDownEditor() override; virtual void SetIsXHTML(bool aXHTML) override { mType = (aXHTML ? eXHTML : eHTML); @@ -146,17 +148,23 @@ public: void GetDomain(nsAString& aDomain); void SetDomain(const nsAString& aDomain, mozilla::ErrorResult& rv); bool IsRegistrableDomainSuffixOfOrEqualTo(const nsAString& aHostSuffixString, const nsACString& aOrigHost); void GetCookie(nsAString& aCookie, mozilla::ErrorResult& rv); void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv); void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound, JS::MutableHandle<JSObject*> aRetval, - mozilla::ErrorResult& rv); + mozilla::ErrorResult& rv) + { + JS::Rooted<JS::Value> v(cx); + if ((aFound = ResolveName(cx, aName, &v, rv))) { + aRetval.set(v.toObjectOrNull()); + } + } void GetSupportedNames(nsTArray<nsString>& aNames); already_AddRefed<nsIDocument> Open(JSContext* cx, const mozilla::dom::Optional<nsAString>& /* unused */, const nsAString& aReplace, mozilla::ErrorResult& aError); already_AddRefed<nsPIDOMWindowOuter> Open(JSContext* cx, const nsAString& aURL,
--- a/dom/network/Connection.cpp +++ b/dom/network/Connection.cpp @@ -2,17 +2,16 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ #include "Connection.h" #include "ConnectionMainThread.h" #include "ConnectionWorker.h" -#include "nsIDOMClassInfo.h" #include "Constants.h" #include "mozilla/Telemetry.h" #include "mozilla/dom/WorkerPrivate.h" /** * We have to use macros here because our leak analysis tool things we are * leaking strings when we have |static const nsString|. Sad :( */
--- a/dom/serviceworkers/ServiceWorker.cpp +++ b/dom/serviceworkers/ServiceWorker.cpp @@ -3,16 +3,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ #include "ServiceWorker.h" #include "nsIDocument.h" #include "nsPIDOMWindow.h" +#include "ServiceWorkerImpl.h" #include "ServiceWorkerManager.h" #include "ServiceWorkerPrivate.h" #include "mozilla/dom/DOMPrefs.h" #include "mozilla/dom/ClientIPCTypes.h" #include "mozilla/dom/ClientState.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h" @@ -57,17 +58,18 @@ ServiceWorker::Create(nsIGlobalObject* a return ref.forget(); } RefPtr<ServiceWorkerInfo> info = reg->GetByDescriptor(aDescriptor); if (!info) { return ref.forget(); } - ref = new ServiceWorker(aOwner, aDescriptor, info); + RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info); + ref = new ServiceWorker(aOwner, aDescriptor, inner); return ref.forget(); } ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal, const ServiceWorkerDescriptor& aDescriptor, ServiceWorker::Inner* aInner) : DOMEventTargetHelper(aGlobal) , mDescriptor(aDescriptor)
new file mode 100644 --- /dev/null +++ b/dom/serviceworkers/ServiceWorkerImpl.cpp @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +#include "ServiceWorkerImpl.h" + +namespace mozilla { +namespace dom { + +ServiceWorkerImpl::~ServiceWorkerImpl() +{ + MOZ_DIAGNOSTIC_ASSERT(!mOuter); + mInfo->RemoveListener(this); +} + +void +ServiceWorkerImpl::AddServiceWorker(ServiceWorker* aWorker) +{ + MOZ_DIAGNOSTIC_ASSERT(!mOuter); + MOZ_DIAGNOSTIC_ASSERT(aWorker); + mOuter = aWorker; + + // Wait to attach to the info as a listener until we have the outer + // set. This is important because the info will try to set the + // state immediately. + mInfo->AddListener(this); +} + +void +ServiceWorkerImpl::RemoveServiceWorker(ServiceWorker* aWorker) +{ + MOZ_DIAGNOSTIC_ASSERT(mOuter); + MOZ_DIAGNOSTIC_ASSERT(mOuter == aWorker); + mOuter = nullptr; +} + +void +ServiceWorkerImpl::PostMessage(ipc::StructuredCloneData&& aData, + const ClientInfo& aClientInfo, + const ClientState& aClientState) +{ + mInfo->PostMessage(Move(aData), aClientInfo, aClientState); +} + +void +ServiceWorkerImpl::SetState(ServiceWorkerState aState) +{ + if (!mOuter) { + return; + } + mOuter->SetState(aState); +} + + +ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo) + : mInfo(aInfo) + , mOuter(nullptr) +{ + MOZ_DIAGNOSTIC_ASSERT(mInfo); +} + +} // namespace dom +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/dom/serviceworkers/ServiceWorkerImpl.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +#ifndef mozilla_dom_ServiceWorkerImpl_h +#define mozilla_dom_ServiceWorkerImpl_h + +#include "ServiceWorker.h" +#include "ServiceWorkerInfo.h" + +namespace mozilla { +namespace dom { + +class ServiceWorkerInfo; + +class ServiceWorkerImpl final : public ServiceWorker::Inner + , public ServiceWorkerInfo::Listener +{ + RefPtr<ServiceWorkerInfo> mInfo; + ServiceWorker* mOuter; + + ~ServiceWorkerImpl(); + + // ServiceWorker::Inner interface + void + AddServiceWorker(ServiceWorker* aWorker) override; + + void + RemoveServiceWorker(ServiceWorker* aWorker) override; + + void + PostMessage(ipc::StructuredCloneData&& aData, + const ClientInfo& aClientInfo, + const ClientState& aClientState) override; + + // ServiceWorkerInfo::Listener interface + void + SetState(ServiceWorkerState aState) override; + +public: + explicit ServiceWorkerImpl(ServiceWorkerInfo* aInfo); + + NS_INLINE_DECL_REFCOUNTING(ServiceWorkerImpl, override); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ServiceWorkerImpl_h
--- a/dom/serviceworkers/ServiceWorkerInfo.cpp +++ b/dom/serviceworkers/ServiceWorkerInfo.cpp @@ -113,17 +113,17 @@ ServiceWorkerInfo::DetachDebugger() return mServiceWorkerPrivate->DetachDebugger(); } namespace { class ChangeStateUpdater final : public Runnable { public: - ChangeStateUpdater(const nsTArray<ServiceWorker*>& aInstances, + ChangeStateUpdater(const nsTArray<ServiceWorkerInfo::Listener*>& aInstances, ServiceWorkerState aState) : Runnable("dom::ChangeStateUpdater") , mState(aState) { for (size_t i = 0; i < aInstances.Length(); ++i) { mInstances.AppendElement(aInstances[i]); } } @@ -132,17 +132,17 @@ public: { for (size_t i = 0; i < mInstances.Length(); ++i) { mInstances[i]->SetState(mState); } return NS_OK; } private: - AutoTArray<RefPtr<ServiceWorker>, 1> mInstances; + AutoTArray<RefPtr<ServiceWorkerInfo::Listener>, 1> mInstances; ServiceWorkerState mState; }; } void ServiceWorkerInfo::UpdateState(ServiceWorkerState aState) { @@ -220,43 +220,30 @@ static uint64_t gServiceWorkerInfoCurren uint64_t ServiceWorkerInfo::GetNextID() const { return ++gServiceWorkerInfoCurrentID; } void -ServiceWorkerInfo::AddServiceWorker(ServiceWorker* aWorker) +ServiceWorkerInfo::AddListener(Listener* aListener) { - MOZ_DIAGNOSTIC_ASSERT(aWorker); -#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED - nsAutoString workerURL; - aWorker->GetScriptURL(workerURL); - MOZ_DIAGNOSTIC_ASSERT( - workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL()))); -#endif - MOZ_ASSERT(!mInstances.Contains(aWorker)); + MOZ_DIAGNOSTIC_ASSERT(aListener); + MOZ_ASSERT(!mInstances.Contains(aListener)); - mInstances.AppendElement(aWorker); - aWorker->SetState(State()); + mInstances.AppendElement(aListener); + aListener->SetState(State()); } void -ServiceWorkerInfo::RemoveServiceWorker(ServiceWorker* aWorker) +ServiceWorkerInfo::RemoveListener(Listener* aListener) { - MOZ_DIAGNOSTIC_ASSERT(aWorker); -#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED - nsAutoString workerURL; - aWorker->GetScriptURL(workerURL); - MOZ_DIAGNOSTIC_ASSERT( - workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL()))); -#endif - - DebugOnly<bool> removed = mInstances.RemoveElement(aWorker); + MOZ_DIAGNOSTIC_ASSERT(aListener); + DebugOnly<bool> removed = mInstances.RemoveElement(aListener); MOZ_ASSERT(removed); } void ServiceWorkerInfo::PostMessage(ipc::StructuredCloneData&& aData, const ClientInfo& aClientInfo, const ClientState& aClientState) {
--- a/dom/serviceworkers/ServiceWorkerInfo.h +++ b/dom/serviceworkers/ServiceWorkerInfo.h @@ -7,33 +7,41 @@ #ifndef mozilla_dom_serviceworkerinfo_h #define mozilla_dom_serviceworkerinfo_h #include "MainThreadUtils.h" #include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState #include "mozilla/dom/WorkerCommon.h" #include "mozilla/OriginAttributes.h" #include "nsIServiceWorkerManager.h" -#include "ServiceWorker.h" namespace mozilla { namespace dom { class ClientInfoAndState; class ServiceWorkerPrivate; /* * Wherever the spec treats a worker instance and a description of said worker * as the same thing; i.e. "Resolve foo with * _GetNewestWorker(serviceWorkerRegistration)", we represent the description * by this class and spawn a ServiceWorker in the right global when required. */ class ServiceWorkerInfo final : public nsIServiceWorkerInfo - , public ServiceWorker::Inner { +public: + class Listener + { + public: + virtual void + SetState(ServiceWorkerState aState) = 0; + + NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING + }; + private: nsCOMPtr<nsIPrincipal> mPrincipal; ServiceWorkerDescriptor mDescriptor; const nsString mCacheName; OriginAttributes mOriginAttributes; // This LoadFlags is only applied to imported scripts, since the main script // has already been downloaded when performing the bytecheck. This LoadFlag is @@ -55,17 +63,17 @@ private: PRTime mActivatedTime; PRTime mRedundantTime; // We hold rawptrs since the ServiceWorker constructor and destructor ensure // addition and removal. // // There is a high chance of there being at least one ServiceWorker // associated with this all the time. - AutoTArray<ServiceWorker*, 1> mInstances; + AutoTArray<Listener*, 1> mInstances; RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate; bool mSkipWaitingFlag; enum { Unknown, Enabled, Disabled @@ -73,32 +81,31 @@ private: ~ServiceWorkerInfo(); // Generates a unique id for the service worker, with zero being treated as // invalid. uint64_t GetNextID() const; - // ServiceWorker::Inner implementation - virtual void - AddServiceWorker(ServiceWorker* aWorker) override; - - virtual void - RemoveServiceWorker(ServiceWorker* aWorker) override; - - virtual void - PostMessage(ipc::StructuredCloneData&& aData, - const ClientInfo& aClientInfo, - const ClientState& aClientState) override; - public: NS_DECL_ISUPPORTS NS_DECL_NSISERVICEWORKERINFO + void + AddListener(Listener* aListener); + + void + RemoveListener(Listener* aListener); + + void + PostMessage(ipc::StructuredCloneData&& aData, + const ClientInfo& aClientInfo, + const ClientState& aClientState); + class ServiceWorkerPrivate* WorkerPrivate() const { MOZ_ASSERT(mServiceWorkerPrivate); return mServiceWorkerPrivate; } nsIPrincipal*
--- a/dom/serviceworkers/ServiceWorkerRegistrar.cpp +++ b/dom/serviceworkers/ServiceWorkerRegistrar.cpp @@ -10,16 +10,17 @@ #include "mozilla/net/MozURL.h" #include "nsIEventTarget.h" #include "nsIInputStream.h" #include "nsILineInputStream.h" #include "nsIObserverService.h" #include "nsIOutputStream.h" #include "nsISafeOutputStream.h" +#include "nsIServiceWorkerManager.h" #include "MainThreadUtils.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/CycleCollectedJSContext.h" #include "mozilla/dom/StorageActivityService.h" #include "mozilla/ErrorNames.h" #include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/BackgroundParent.h" @@ -31,16 +32,17 @@ #include "nsAppDirectoryServiceDefs.h" #include "nsContentUtils.h" #include "nsDirectoryServiceUtils.h" #include "nsNetCID.h" #include "nsNetUtil.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" #include "nsXULAppAPI.h" +#include "ServiceWorkerUtils.h" using namespace mozilla::ipc; namespace mozilla { namespace dom { namespace {
--- a/dom/serviceworkers/moz.build +++ b/dom/serviceworkers/moz.build @@ -27,16 +27,17 @@ EXPORTS.mozilla.dom += [ ] UNIFIED_SOURCES += [ 'ServiceWorker.cpp', 'ServiceWorkerContainer.cpp', 'ServiceWorkerContainerImpl.cpp', 'ServiceWorkerDescriptor.cpp', 'ServiceWorkerEvents.cpp', + 'ServiceWorkerImpl.cpp', 'ServiceWorkerInfo.cpp', 'ServiceWorkerInterceptController.cpp', 'ServiceWorkerJob.cpp', 'ServiceWorkerJobQueue.cpp', 'ServiceWorkerManager.cpp', 'ServiceWorkerManagerChild.cpp', 'ServiceWorkerManagerParent.cpp', 'ServiceWorkerManagerService.cpp',
--- a/dom/tests/mochitest/general/test_consoleAPI.html +++ b/dom/tests/mochitest/general/test_consoleAPI.html @@ -27,16 +27,17 @@ function doTest() { "exception": "function", "debug": "function", "trace": "function", "dir": "function", "group": "function", "groupCollapsed": "function", "groupEnd": "function", "time": "function", + "timeLog": "function", "timeEnd": "function", "profile": "function", "profileEnd": "function", "assert": "function", "count": "function", "table": "function", "clear": "function", "dirxml": "function",
--- a/dom/tests/mochitest/general/test_interfaces.js +++ b/dom/tests/mochitest/general/test_interfaces.js @@ -252,38 +252,32 @@ var interfaceNamesInGlobalScope = {name: "CSSMediaRule", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSMozDocumentRule", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSNamespaceRule", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSPageRule", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! - {name: "CSSPrimitiveValue", insecureContext: true}, -// IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSPseudoElement", insecureContext: true, release: false}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSRule", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSRuleList", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSStyleDeclaration", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSStyleRule", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSStyleSheet", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSSupportsRule", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CSSTransition", insecureContext: true, release: false}, // IMPORTANT: Do not change this list without review from a DOM peer! - {name: "CSSValue", insecureContext: true}, -// IMPORTANT: Do not change this list without review from a DOM peer! - {name: "CSSValueList", insecureContext: true}, -// IMPORTANT: Do not change this list without review from a DOM peer! {name: "CustomElementRegistry", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "CustomEvent", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "DataTransfer", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "DataTransferItem", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! @@ -810,24 +804,20 @@ var interfaceNamesInGlobalScope = {name: "PushSubscription", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "PushSubscriptionOptions", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "RadioNodeList", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "Range", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! - {name: "Rect", insecureContext: true}, -// IMPORTANT: Do not change this list without review from a DOM peer! {name: "Request", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "Response", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! - {name: "RGBColor", insecureContext: true}, -// IMPORTANT: Do not change this list without review from a DOM peer! {name: "RTCCertificate", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "RTCDataChannel", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "RTCDataChannelEvent", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer! {name: "RTCDTMFSender", insecureContext: true}, // IMPORTANT: Do not change this list without review from a DOM peer!
deleted file mode 100644 --- a/dom/webidl/CSSPrimitiveValue.webidl +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. - */ - -interface CSSPrimitiveValue : CSSValue { - - // UnitTypes - const unsigned short CSS_UNKNOWN = 0; - const unsigned short CSS_NUMBER = 1; - const unsigned short CSS_PERCENTAGE = 2; - const unsigned short CSS_EMS = 3; - const unsigned short CSS_EXS = 4; - const unsigned short CSS_PX = 5; - const unsigned short CSS_CM = 6; - const unsigned short CSS_MM = 7; - const unsigned short CSS_IN = 8; - const unsigned short CSS_PT = 9; - const unsigned short CSS_PC = 10; - const unsigned short CSS_DEG = 11; - const unsigned short CSS_RAD = 12; - const unsigned short CSS_GRAD = 13; - const unsigned short CSS_MS = 14; - const unsigned short CSS_S = 15; - const unsigned short CSS_HZ = 16; - const unsigned short CSS_KHZ = 17; - const unsigned short CSS_DIMENSION = 18; - const unsigned short CSS_STRING = 19; - const unsigned short CSS_URI = 20; - const unsigned short CSS_IDENT = 21; - const unsigned short CSS_ATTR = 22; - const unsigned short CSS_COUNTER = 23; - const unsigned short CSS_RECT = 24; - const unsigned short CSS_RGBCOLOR = 25; - - readonly attribute unsigned short primitiveType; - [Throws] - void setFloatValue(unsigned short unitType, - float floatValue); - [Throws] - float getFloatValue(unsigned short unitType); - [Throws] - void setStringValue(unsigned short stringType, - DOMString stringValue); - [Throws] - DOMString getStringValue(); - [Throws] - void getCounterValue(); // always throws - [Throws] - Rect getRectValue(); - [Throws] - RGBColor getRGBColorValue(); -};
deleted file mode 100644 --- a/dom/webidl/CSSValue.webidl +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. - */ - -interface CSSValue { - - // UnitTypes - const unsigned short CSS_INHERIT = 0; - const unsigned short CSS_PRIMITIVE_VALUE = 1; - const unsigned short CSS_VALUE_LIST = 2; - const unsigned short CSS_CUSTOM = 3; - - [Throws] - attribute DOMString cssText; - - readonly attribute unsigned short cssValueType; -};
deleted file mode 100644 --- a/dom/webidl/CSSValueList.webidl +++ /dev/null @@ -1,10 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. - */ - -interface CSSValueList : CSSValue { - readonly attribute unsigned long length; - getter CSSValue? item(unsigned long index); -};
--- a/dom/webidl/Console.webidl +++ b/dom/webidl/Console.webidl @@ -49,16 +49,18 @@ namespace console { void groupCollapsed(any... data); [UseCounter] void groupEnd(); // Timing [UseCounter] void time(optional DOMString label = "default"); [UseCounter] + void timeLog(optional DOMString label = "default", any... data); + [UseCounter] void timeEnd(optional DOMString label = "default"); // Mozilla only or Webcompat methods [UseCounter] void _exception(any... data); [UseCounter] void timeStamp(optional any data); @@ -116,17 +118,17 @@ dictionary ConsoleStackEntry { DOMString functionName = ""; DOMString? asyncCause; }; dictionary ConsoleTimerStart { DOMString name = ""; }; -dictionary ConsoleTimerEnd { +dictionary ConsoleTimerLogOrEnd { DOMString name = ""; double duration = 0; }; dictionary ConsoleTimerError { DOMString error = ""; DOMString name = ""; }; @@ -160,32 +162,34 @@ interface ConsoleInstance { // Grouping void group(any... data); void groupCollapsed(any... data); void groupEnd(); // Timing void time(optional DOMString label = "default"); + void timeLog(optional DOMString label = "default", any... data); void timeEnd(optional DOMString label = "default"); // Mozilla only or Webcompat methods void _exception(any... data); void timeStamp(optional any data); void profile(any... data); void profileEnd(any... data); }; callback ConsoleInstanceDumpCallback = void (DOMString message); enum ConsoleLogLevel { - "All", "Debug", "Log", "Info", "Clear", "Trace", "TimeEnd", "Time", "Group", - "GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error", "Off" + "All", "Debug", "Log", "Info", "Clear", "Trace", "TimeLog", "TimeEnd", "Time", + "Group", "GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error", + "Off" }; dictionary ConsoleInstanceOptions { // An optional function to intercept all strings written to stdout. ConsoleInstanceDumpCallback dump; // An optional prefix string to be printed before the actual logged message. DOMString prefix = "";
deleted file mode 100644 --- a/dom/webidl/RGBColor.webidl +++ /dev/null @@ -1,17 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. - * - * The origin of this IDL file is - * http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-RGBColor - */ - -interface RGBColor { - readonly attribute CSSPrimitiveValue red; - readonly attribute CSSPrimitiveValue green; - readonly attribute CSSPrimitiveValue blue; - - // mozilla specific - readonly attribute CSSPrimitiveValue alpha; -};
deleted file mode 100644 --- a/dom/webidl/Rect.webidl +++ /dev/null @@ -1,12 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. - */ - -interface Rect { - readonly attribute CSSPrimitiveValue top; - readonly attribute CSSPrimitiveValue right; - readonly attribute CSSPrimitiveValue bottom; - readonly attribute CSSPrimitiveValue left; -};
--- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -436,27 +436,24 @@ WEBIDL_FILES = [ 'CSSImportRule.webidl', 'CSSKeyframeRule.webidl', 'CSSKeyframesRule.webidl', 'CSSLexer.webidl', 'CSSMediaRule.webidl', 'CSSMozDocumentRule.webidl', 'CSSNamespaceRule.webidl', 'CSSPageRule.webidl', - 'CSSPrimitiveValue.webidl', 'CSSPseudoElement.webidl', 'CSSRule.webidl', 'CSSRuleList.webidl', 'CSSStyleDeclaration.webidl', 'CSSStyleRule.webidl', 'CSSStyleSheet.webidl', 'CSSSupportsRule.webidl', 'CSSTransition.webidl', - 'CSSValue.webidl', - 'CSSValueList.webidl', 'CustomElementRegistry.webidl', 'DataTransfer.webidl', 'DataTransferItem.webidl', 'DataTransferItemList.webidl', 'DecoderDoctorNotification.webidl', 'DedicatedWorkerGlobalScope.webidl', 'DelayNode.webidl', 'DeviceMotionEvent.webidl', @@ -733,20 +730,18 @@ WEBIDL_FILES = [ 'PushEvent.webidl', 'PushManager.webidl', 'PushManager.webidl', 'PushMessageData.webidl', 'PushSubscription.webidl', 'PushSubscriptionOptions.webidl', 'RadioNodeList.webidl', 'Range.webidl', - 'Rect.webidl', 'Request.webidl', 'Response.webidl', - 'RGBColor.webidl', 'RTCStatsReport.webidl', 'Screen.webidl', 'ScreenOrientation.webidl', 'ScriptProcessorNode.webidl', 'ScrollAreaEvent.webidl', 'ScrollBoxObject.webidl', 'Selection.webidl', 'ServiceWorker.webidl',
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp +++ b/editor/libeditor/HTMLAbsPositionEditor.cpp @@ -9,17 +9,16 @@ #include "HTMLEditorObjectResizerUtils.h" #include "HTMLEditRules.h" #include "HTMLEditUtils.h" #include "TextEditUtils.h" #include "mozilla/EditAction.h" #include "mozilla/EditorUtils.h" #include "mozilla/Preferences.h" #include "mozilla/TextEditRules.h" -#include "mozilla/dom/CSSPrimitiveValueBinding.h" #include "mozilla/dom/Selection.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/EventTarget.h" #include "mozilla/mozalloc.h" #include "nsAString.h" #include "nsAlgorithm.h" #include "nsCOMPtr.h" #include "nsComputedDOMStyle.h"
--- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp +++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp @@ -1,16 +1,15 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ #include "mozilla/HTMLEditor.h" #include "mozilla/Attributes.h" -#include "mozilla/dom/CSSPrimitiveValueBinding.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/EventTarget.h" #include "mozilla/mozalloc.h" #include "nsAString.h" #include "nsCOMPtr.h" #include "nsComputedDOMStyle.h" #include "nsDebug.h" #include "nsError.h"
--- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -4206,25 +4206,26 @@ gfxFontStyle::gfxFontStyle(FontSlantStyl NS_WARNING("null language"); language = nsGkAtoms::x_western; } } PLDHashNumber gfxFontStyle::Hash() const { - return mozilla::HashGeneric(systemFont, style.ForHash(), - stretch.ForHash(), weight.ForHash(), - size, sizeAdjust, - nsRefPtrHashKey<nsAtom>::HashKey(language)); - /* XXX - return (style + (systemFont << 7) + (weight.ForHash() << 8) + - uint32_t(size*1000) + int32_t(sizeAdjust*1000)) ^ - nsRefPtrHashKey<nsAtom>::HashKey(language); - */ + uint32_t hash = + variationSettings.IsEmpty() + ? 0 + : mozilla::HashBytes(variationSettings.Elements(), + variationSettings.Length() * + sizeof(gfxFontVariation)); + return mozilla::AddToHash(hash, systemFont, style.ForHash(), + stretch.ForHash(), weight.ForHash(), + size, int32_t(sizeAdjust * 1000.0f), + nsRefPtrHashKey<nsAtom>::HashKey(language)); } void gfxFontStyle::AdjustForSubSuperscript(int32_t aAppUnitsPerDevPixel) { MOZ_ASSERT(variantSubSuper != NS_FONT_VARIANT_POSITION_NORMAL && baselineOffset == 0, "can't adjust this style for sub/superscript");
--- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -1519,18 +1519,16 @@ WeightDistance(const gfxFontEntry* aFont if (distance < 0.0) { distance = kReverseDistance - distance; } distance += addedDistance; } return distance; } -#define MAX_DISTANCE 1.0e20 // >> than any WeightStyleStretchDistance result - static inline double WeightStyleStretchDistance(gfxFontEntry* aFontEntry, const gfxFontStyle& aTargetStyle) { double stretchDist = StretchDistance(aFontEntry, aTargetStyle.stretch); double styleDist = StyleDistance(aFontEntry, aTargetStyle.style); double weightDist = WeightDistance(aFontEntry, aTargetStyle.weight); @@ -1620,17 +1618,17 @@ gfxFontFamily::FindAllFontsForStyle(cons // given but the 99% use case is only a single font entry per // weight/style/stretch distance value. To optimize this, only add entries // to the matched font array when another entry already has the same // weight/style/stretch distance and add the last matched font entry. For // normal platform fonts with a single font entry for each // weight/style/stretch combination, only the last matched font entry will // be added. - double minDistance = MAX_DISTANCE; + double minDistance = INFINITY; gfxFontEntry* matched = nullptr; // iterate in forward order so that faces like 'Bold' are matched before // matching style distance faces such as 'Bold Outline' (see bug 1185812) for (uint32_t i = 0; i < count; i++) { fe = mAvailableFonts[i]; // weight/style/stretch priority: stretch >> style >> weight double distance = WeightStyleStretchDistance(fe, aFontStyle); if (distance < minDistance) { @@ -1730,137 +1728,91 @@ gfxFontFamily::ContainsFace(gfxFontEntry #endif void gfxFontFamily::LocalizedName(nsAString& aLocalizedName) { // just return the primary name; subclasses should override aLocalizedName = mName; } -// metric for how close a given font matches a style -static float -CalcStyleMatch(gfxFontEntry *aFontEntry, const gfxFontStyle *aStyle) -{ - float rank = 0; - if (aStyle) { - // TODO: stretch - - // italics - bool wantUpright = aStyle->style.IsNormal(); - if (aFontEntry->IsUpright() == wantUpright) { - rank += 5000.0f; - } - - // measure of closeness of weight to the desired value - if (aFontEntry->Weight().Min() > aStyle->weight) { - rank += 1000.0f - (aFontEntry->Weight().Min() - aStyle->weight); - } else if (aFontEntry->Weight().Max() < aStyle->weight) { - rank += 1000.0f - (aStyle->weight - aFontEntry->Weight().Max()); - } else { - rank += 2000.0f; // the font supports the exact weight wanted - } - } else { - // if no font to match, prefer non-bold, non-italic fonts - if (aFontEntry->IsUpright()) { - rank += 2000.0f; - } - if (aFontEntry->Weight().Min() <= FontWeight(500)) { - rank += 1000.0f; - } - } - - return rank; -} - -#define RANK_MATCHED_CMAP 10000.0f - void -gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData) +gfxFontFamily::FindFontForChar(GlobalFontMatch* aMatchData) { if (mFamilyCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) { // none of the faces in the family support the required char, // so bail out immediately return; } - gfxFontEntry *fe = - FindFontForStyle(aMatchData->mStyle ? *aMatchData->mStyle - : gfxFontStyle(), - true); + gfxFontEntry* fe = + FindFontForStyle(aMatchData->mStyle, /*aIgnoreSizeTolerance*/ true); + if (!fe || fe->SkipDuringSystemFallback()) { + return; + } - if (fe && !fe->SkipDuringSystemFallback()) { - float rank = 0; + float distance = INFINITY; - if (fe->HasCharacter(aMatchData->mCh)) { - rank += RANK_MATCHED_CMAP; - aMatchData->mCount++; - - LogModule* log = gfxPlatform::GetLog(eGfxLog_textrun); + if (fe->HasCharacter(aMatchData->mCh)) { + aMatchData->mCount++; - if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Debug))) { - uint32_t unicodeRange = FindCharUnicodeRange(aMatchData->mCh); - Script script = GetScriptCode(aMatchData->mCh); - MOZ_LOG(log, LogLevel::Debug,\ - ("(textrun-systemfallback-fonts) char: u+%6.6x " - "unicode-range: %d script: %d match: [%s]\n", - aMatchData->mCh, - unicodeRange, int(script), - NS_ConvertUTF16toUTF8(fe->Name()).get())); - } + LogModule* log = gfxPlatform::GetLog(eGfxLog_textrun); - // omitting from original windows code -- family name, lang group, pitch - // not available in current FontEntry implementation - rank += CalcStyleMatch(fe, aMatchData->mStyle); - } else if (!fe->IsNormalStyle()) { - // If style/weight/stretch was not Normal, see if we can - // fall back to a next-best face (e.g. Arial Black -> Bold, - // or Arial Narrow -> Regular). - GlobalFontMatch data(aMatchData->mCh, aMatchData->mStyle); - SearchAllFontsForChar(&data); - if (data.mMatchRank >= RANK_MATCHED_CMAP) { - fe = data.mBestMatch; - rank = data.mMatchRank; - } else { - return; - } - } else { - return; + if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Debug))) { + uint32_t unicodeRange = FindCharUnicodeRange(aMatchData->mCh); + Script script = GetScriptCode(aMatchData->mCh); + MOZ_LOG(log, LogLevel::Debug,\ + ("(textrun-systemfallback-fonts) char: u+%6.6x " + "unicode-range: %d script: %d match: [%s]\n", + aMatchData->mCh, + unicodeRange, int(script), + NS_ConvertUTF16toUTF8(fe->Name()).get())); } - aMatchData->mCmapsTested++; - - // xxx - add whether AAT font with morphing info for specific lang groups + distance = WeightStyleStretchDistance(fe, aMatchData->mStyle); + } else if (!fe->IsNormalStyle()) { + // If style/weight/stretch was not Normal, see if we can + // fall back to a next-best face (e.g. Arial Black -> Bold, + // or Arial Narrow -> Regular). + GlobalFontMatch data(aMatchData->mCh, aMatchData->mStyle); + SearchAllFontsForChar(&data); + if (std::isfinite(data.mMatchDistance)) { + fe = data.mBestMatch; + distance = data.mMatchDistance; + } + } + aMatchData->mCmapsTested++; - if (rank > aMatchData->mMatchRank - || (rank == aMatchData->mMatchRank && - Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0)) - { - aMatchData->mBestMatch = fe; - aMatchData->mMatchedFamily = this; - aMatchData->mMatchRank = rank; - } + if (std::isinf(distance)) { + return; + } + + if (distance < aMatchData->mMatchDistance || + (distance == aMatchData->mMatchDistance && + Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0)) { + aMatchData->mBestMatch = fe; + aMatchData->mMatchedFamily = this; + aMatchData->mMatchDistance = distance; } } void -gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch *aMatchData) +gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch* aMatchData) { uint32_t i, numFonts = mAvailableFonts.Length(); for (i = 0; i < numFonts; i++) { gfxFontEntry *fe = mAvailableFonts[i]; if (fe && fe->HasCharacter(aMatchData->mCh)) { - float rank = RANK_MATCHED_CMAP; - rank += CalcStyleMatch(fe, aMatchData->mStyle); - if (rank > aMatchData->mMatchRank - || (rank == aMatchData->mMatchRank && + float distance = WeightStyleStretchDistance(fe, aMatchData->mStyle); + if (distance < aMatchData->mMatchDistance + || (distance == aMatchData->mMatchDistance && Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0)) { aMatchData->mBestMatch = fe; aMatchData->mMatchedFamily = this; - aMatchData->mMatchRank = rank; + aMatchData->mMatchDistance = distance; } } } } /*virtual*/ gfxFontFamily::~gfxFontFamily() {
--- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -19,16 +19,17 @@ #include "MainThreadUtils.h" #include "nsUnicodeScriptCodes.h" #include "nsDataHashtable.h" #include "harfbuzz/hb.h" #include "mozilla/FontPropertyTypes.h" #include "mozilla/gfx/2D.h" #include "mozilla/UniquePtr.h" #include "mozilla/WeakPtr.h" +#include <math.h> typedef struct gr_face gr_face; #ifdef DEBUG #include <stdio.h> #endif struct gfxFontStyle; @@ -685,30 +686,29 @@ gfxFontEntry::SupportsBold() ((mRangeFlags & RangeFlags::eAutoWeight) == RangeFlags::eAutoWeight && HasBoldVariableWeight()); } // used when iterating over all fonts looking for a match for a given character struct GlobalFontMatch { GlobalFontMatch(const uint32_t aCharacter, - const gfxFontStyle *aStyle) : - mCh(aCharacter), mStyle(aStyle), - mMatchRank(0.0f), mCount(0), mCmapsTested(0) + const gfxFontStyle& aStyle) : + mStyle(aStyle), mCh(aCharacter), + mCount(0), mCmapsTested(0), mMatchDistance(INFINITY) { - } + RefPtr<gfxFontEntry> mBestMatch; // current best match + RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to + const gfxFontStyle& mStyle; // style to match const uint32_t mCh; // codepoint to be matched - const gfxFontStyle* mStyle; // style to match - float mMatchRank; // metric indicating closest match - RefPtr<gfxFontEntry> mBestMatch; // current best match - RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to uint32_t mCount; // number of fonts matched uint32_t mCmapsTested; // number of cmaps tested + float mMatchDistance; // metric indicating closest match }; class gfxFontFamily { public: // Used by stylo NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontFamily) explicit gfxFontFamily(const nsAString& aName) : @@ -781,20 +781,20 @@ public: virtual void FindAllFontsForStyle(const gfxFontStyle& aFontStyle, nsTArray<gfxFontEntry*>& aFontEntryList, bool aIgnoreSizeTolerance = false); // checks for a matching font within the family // used as part of the font fallback process - void FindFontForChar(GlobalFontMatch *aMatchData); + void FindFontForChar(GlobalFontMatch* aMatchData); // checks all fonts for a matching font within the family - void SearchAllFontsForChar(GlobalFontMatch *aMatchData); + void SearchAllFontsForChar(GlobalFontMatch* aMatchData); // read in other family names, if any, and use functor to add each into cache virtual void ReadOtherFamilyNames(gfxPlatformFontList *aPlatformFontList); // helper method for reading localized family names from the name table // of a single face static void ReadOtherFamilyNamesForFace(const nsAString& aFamilyName, const char *aNameData,
--- a/gfx/thebes/gfxMacFont.cpp +++ b/gfx/thebes/gfxMacFont.cpp @@ -18,16 +18,23 @@ #include "gfxTextRun.h" #include "nsCocoaFeatures.h" #include "cairo-quartz.h" using namespace mozilla; using namespace mozilla::gfx; +template<class T> +struct TagEquals { + bool Equals(const T& aIter, uint32_t aTag) const { + return aIter.mTag == aTag; + } +}; + gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont, MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyle) : gfxFont(aUnscaledFont, aFontEntry, aFontStyle), mCGFont(nullptr), mCTFont(nullptr), mFontFace(nullptr), mFontSmoothingBackgroundColor(aFontStyle->fontSmoothingBackgroundColor), @@ -42,16 +49,65 @@ gfxMacFont::gfxMacFont(const RefPtr<Unsc return; } // Get the variation settings needed to instantiate the fontEntry // for a particular fontStyle. AutoTArray<gfxFontVariation,4> vars; aFontEntry->GetVariationsForStyle(vars, *aFontStyle); + // Because of a Core Text bug, we need to ensure that if the font has + // an 'opsz' axis, it is always explicitly set, and NOT to the font's + // default value. (See bug 1457417.) + // We record the result of searching the font's axes in the font entry, + // so that this only has to be done by the first instance created for + // a given font resource. + const uint32_t kOpszTag = HB_TAG('o','p','s','z'); + + if (!aFontEntry->mCheckedForOpszAxis) { + aFontEntry->mCheckedForOpszAxis = true; + AutoTArray<gfxFontVariationAxis,4> axes; + aFontEntry->GetVariationAxes(axes); + auto index = + axes.IndexOf(kOpszTag, 0, TagEquals<gfxFontVariationAxis>()); + if (index == axes.NoIndex) { + aFontEntry->mHasOpszAxis = false; + } else { + const auto& axis = axes[index]; + aFontEntry->mHasOpszAxis = true; + aFontEntry->mOpszAxis = axis; + // Pick a slightly-adjusted version of the default that we'll + // use to work around Core Text's habit of ignoring any attempt + // to explicitly set the default value. + aFontEntry->mAdjustedDefaultOpsz = + axis.mDefaultValue == axis.mMinValue + ? axis.mDefaultValue + 0.001f + : axis.mDefaultValue - 0.001f; + } + } + + // Add 'opsz' if not present, or tweak its value if it looks too close + // to the default (after clamping to the font's available range). + if (aFontEntry->mHasOpszAxis) { + auto index = + vars.IndexOf(kOpszTag, 0, TagEquals<gfxFontVariation>()); + if (index == vars.NoIndex) { + gfxFontVariation opsz{kOpszTag, aFontEntry->mAdjustedDefaultOpsz}; + vars.AppendElement(opsz); + } else { + // Figure out a "safe" value that Core Text won't ignore. + auto& value = vars[index].mValue; + auto& axis = aFontEntry->mOpszAxis; + value = fmin(fmax(value, axis.mMinValue), axis.mMaxValue); + if (abs(value - axis.mDefaultValue) < 0.001f) { + value = aFontEntry->mAdjustedDefaultOpsz; + } + } + } + mCGFont = UnscaledFontMac::CreateCGFontWithVariations(baseFont, vars.Length(), vars.Elements()); if (!mCGFont) { ::CFRetain(baseFont); mCGFont = baseFont; }
--- a/gfx/thebes/gfxMacPlatformFontList.h +++ b/gfx/thebes/gfxMacPlatformFontList.h @@ -25,16 +25,17 @@ class gfxMacPlatformFontList; // a single member of a font family (i.e. a single face, such as Times Italic) class MacOSFontEntry : public gfxFontEntry { public: friend class gfxMacPlatformFontList; + friend class gfxMacFont; MacOSFontEntry(const nsAString& aPostscriptName, WeightRange aWeight, bool aIsStandardFace = false, double aSizeHint = 0.0); // for use with data fonts MacOSFontEntry(const nsAString& aPostscriptName, CGFontRef aFontRef, WeightRange aWeight, StretchRange aStretch, SlantStyleRange aStyle, @@ -99,16 +100,29 @@ protected: bool mRequiresAAT; bool mIsCFF; bool mIsCFFInitialized; bool mHasVariations; bool mHasVariationsInitialized; bool mHasAATSmallCaps; bool mHasAATSmallCapsInitialized; bool mCheckedForTracking; + + // To work around Core Text's mishandling of the default value for 'opsz', + // we need to record whether the font has an a optical size axis, what its + // range and default values are, and a usable close-to-default alternative. + // (See bug 1457417 for details.) + // These fields are used by gfxMacFont, but stored in the font entry so + // that only a single font instance needs to inspect the available + // variations. + bool mCheckedForOpszAxis; + bool mHasOpszAxis; + gfxFontVariationAxis mOpszAxis; + float mAdjustedDefaultOpsz; + nsTHashtable<nsUint32HashKey> mAvailableTables; mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont; // For AAT font being shaped by Core Text, a strong reference to the 'trak' // table (if present). hb_blob_t* mTrakTable; // Cached pointers to tables within 'trak', initialized by ParseTrakTable.
--- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -376,16 +376,17 @@ MacOSFontEntry::MacOSFontEntry(const nsA mRequiresAAT(false), mIsCFF(false), mIsCFFInitialized(false), mHasVariations(false), mHasVariationsInitialized(false), mHasAATSmallCaps(false), mHasAATSmallCapsInitialized(false), mCheckedForTracking(false), + mCheckedForOpszAxis(false), mTrakTable(nullptr), mTrakValues(nullptr), mTrakSizeTable(nullptr) { mWeightRange = aWeight; } MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, @@ -402,16 +403,17 @@ MacOSFontEntry::MacOSFontEntry(const nsA mRequiresAAT(false), mIsCFF(false), mIsCFFInitialized(false), mHasVariations(false), mHasVariationsInitialized(false), mHasAATSmallCaps(false), mHasAATSmallCapsInitialized(false), mCheckedForTracking(false), + mCheckedForOpszAxis(false), mTrakTable(nullptr), mTrakValues(nullptr), mTrakSizeTable(nullptr) { mFontRef = aFontRef; mFontRefInitialized = true; ::CFRetain(mFontRef);
--- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -677,17 +677,17 @@ gfxPlatformFontList::CommonFontFallback( return fontEntry; } // If we requested a styled font (bold and/or italic), and the char // was not available, check other faces of the family. if (!fontEntry->IsNormalStyle()) { // If style/weight/stretch was not Normal, see if we can // fall back to a next-best face (e.g. Arial Black -> Bold, // or Arial Narrow -> Regular). - GlobalFontMatch data(aCh, aMatchStyle); + GlobalFontMatch data(aCh, *aMatchStyle); fallback->SearchAllFontsForChar(&data); if (data.mBestMatch) { *aMatchedFamily = fallback; return data.mBestMatch; } } } } @@ -710,17 +710,17 @@ gfxPlatformFontList::GlobalFontFallback( PlatformGlobalFontFallback(aCh, aRunScript, aMatchStyle, aMatchedFamily); if (fe) { return fe; } } // otherwise, try to find it among local fonts - GlobalFontMatch data(aCh, aMatchStyle); + GlobalFontMatch data(aCh, *aMatchStyle); // iterate over all font families to find a font that support the character for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) { RefPtr<gfxFontFamily>& family = iter.Data(); // evaluate all fonts in this family for a match family->FindFontForChar(&data); } @@ -1716,16 +1716,17 @@ gfxPlatformFontList::ClearLangGroupPrefF i < eFontPrefLang_First + eFontPrefLang_Count; i++) { auto& prefFontsLangGroup = mLangGroupPrefFonts[i]; for (uint32_t j = eFamily_generic_first; j < eFamily_generic_first + eFamily_generic_count; j++) { prefFontsLangGroup[j] = nullptr; } } mCJKPrefLangs.Clear(); + mEmojiPrefFont = nullptr; } // Support for memory reporting // this is also used by subclasses that hold additional font tables /*static*/ size_t gfxPlatformFontList::SizeOfFontFamilyTableExcludingThis( const FontFamilyTable& aTable,
--- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -2794,17 +2794,17 @@ gfxFontGroup::GetEllipsisTextRun(int32_t // fontgroup's life mCachedEllipsisTextRun->ReleaseFontGroup(); return mCachedEllipsisTextRun.get(); } gfxFont* gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh) { - GlobalFontMatch data(aCh, &mStyle); + GlobalFontMatch data(aCh, mStyle); aFamily->SearchAllFontsForChar(&data); gfxFontEntry* fe = data.mBestMatch; if (!fe) { return nullptr; } return fe->FindOrMakeFont(&mStyle); }
--- a/js/src/builtin/Array.cpp +++ b/js/src/builtin/Array.cpp @@ -775,17 +775,19 @@ js::ArraySetLength(JSContext* cx, Handle // know in case that sparse indexed element is non-configurable, as // that element must prevent any deletions below it. Bug 586842 should // fix this inefficiency by moving indexed storage to be entirely // separate from non-indexed storage. // A second reason for this optimization to be invalid is an active // for..in iteration over the array. Keys deleted before being reached // during the iteration must not be visited, and suppressing them here // would be too costly. - if (!arr->isIndexed() && !MaybeInIteration(arr, cx)) { + // This optimization is also invalid when there are sealed + // (non-configurable) elements. + if (!arr->isIndexed() && !MaybeInIteration(arr, cx) && !arr->denseElementsAreSealed()) { if (!arr->maybeCopyElementsForWrite(cx)) return false; uint32_t oldCapacity = arr->getDenseCapacity(); uint32_t oldInitializedLength = arr->getDenseInitializedLength(); MOZ_ASSERT(oldCapacity >= oldInitializedLength); if (oldInitializedLength > newLen) arr->setDenseInitializedLength(newLen);
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/non-extensible-elements7.js @@ -0,0 +1,42 @@ +// Test array.length setter on non-extensible/sealed/frozen arrays. +"use strict"; + +load(libdir + "asserts.js"); + +function testNonExtensible() { + var a = [1, 2, 3, , ,]; + Object.preventExtensions(a); + for (var i = 0; i < 10; i++) + a.length = 10; + assertEq(a.length, 10); + for (var i = 0; i < 10; i++) + a.length = 0; + assertEq(a.length, 0); + assertEq(a.toString(), ""); +} +testNonExtensible(); + +function testSealed() { + var a = [1, 2, 3, , ,]; + Object.seal(a); + for (var i = 0; i < 10; i++) + a.length = 10; + assertEq(a.length, 10); + for (var i = 0; i < 10; i++) + assertThrowsInstanceOf(() => a.length = 0, TypeError); + assertEq(a.length, 3); + assertEq(a.toString(), "1,2,3"); +} +testSealed(); + +function testFrozen() { + var a = [1, 2, 3, , ,]; + Object.freeze(a); + for (var i = 0; i < 10; i++) + assertThrowsInstanceOf(() => a.length = 10, TypeError); + for (var i = 0; i < 10; i++) + assertThrowsInstanceOf(() => a.length = 0, TypeError); + assertEq(a.length, 5); + assertEq(a.toString(), "1,2,3,,"); +} +testFrozen();
--- a/js/src/jit-test/tests/wasm/gc/anyref.js +++ b/js/src/jit-test/tests/wasm/gc/anyref.js @@ -145,21 +145,28 @@ assertEq(exports.ref_or_null(baguette, 0 let ref = exports.ref_or_null(baguette, 1); assertEq(ref, baguette); assertEq(ref.calories, baguette.calories); ref = exports.nested(baguette, 0); assertEq(ref, baguette); assertEq(ref.calories, baguette.calories); -if (wasmDebuggingIsSupported()) { - let g = newGlobal(); - let dbg = new Debugger(g); - g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`); -} +// Make sure grow-memory isn't blocked by the lack of gc. +(function() { + assertEq(wasmEvalText(`(module + (memory 0 64) + (func (export "f") (param anyref) (result i32) + i32.const 10 + grow_memory + drop + current_memory + ) +)`).exports.f({}), 10); +})(); // More interesting use cases about control flow joins. function assertJoin(body) { let val = { i: -1 }; assertEq(wasmEvalText(`(module (func (export "test") (param $ref anyref) (param $i i32) (result anyref) ${body}
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/wasm/gc/debugger.js @@ -0,0 +1,35 @@ +if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) { + quit(0); +} + +(function() { + let g = newGlobal(); + let dbg = new Debugger(g); + g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`); +})(); + +(function() { + var g = newGlobal(); + g.parent = this; + + let src = ` + (module + (func (export "func") (result anyref) (param $ref anyref) + get_local $ref + ) + ) + `; + + g.eval(` + var obj = { somekey: 'somevalue' }; + + Debugger(parent).onEnterFrame = function(frame) { + let v = frame.environment.getVariable('var0'); + assertEq(typeof v === 'object', true); + assertEq(typeof v.somekey === 'string', true); + assertEq(v.somekey === 'somevalue', true); + }; + + new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(\`${src}\`))).exports.func(obj); + `); +})();
--- a/js/src/jit/CacheIRCompiler.cpp +++ b/js/src/jit/CacheIRCompiler.cpp @@ -126,16 +126,18 @@ CacheRegisterAllocator::useFixedValueReg loc.setValueReg(reg); return reg; } Register CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId) { + MOZ_ASSERT(!addedFailurePath_); + OperandLocation& loc = operandLocations_[typedId.id()]; switch (loc.kind()) { case OperandLocation::PayloadReg: currentOpRegs_.add(loc.payloadReg()); return loc.payloadReg(); case OperandLocation::ValueReg: { // It's possible the value is still boxed: as an optimization, we unbox @@ -201,16 +203,18 @@ CacheRegisterAllocator::useRegister(Macr } MOZ_CRASH(); } ConstantOrRegister CacheRegisterAllocator::useConstantOrRegister(MacroAssembler& masm, ValOperandId val) { + MOZ_ASSERT(!addedFailurePath_); + OperandLocation& loc = operandLocations_[val.id()]; switch (loc.kind()) { case OperandLocation::Constant: return loc.constant(); case OperandLocation::PayloadReg: case OperandLocation::PayloadStack: { JSValueType payloadType = loc.payloadType(); @@ -231,27 +235,31 @@ CacheRegisterAllocator::useConstantOrReg } MOZ_CRASH(); } Register CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId typedId) { + MOZ_ASSERT(!addedFailurePath_); + OperandLocation& loc = operandLocations_[typedId.id()]; MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized); Register reg = allocateRegister(masm); loc.setPayloadReg(reg, typedId.type()); return reg; } ValueOperand CacheRegisterAllocator::defineValueRegister(MacroAssembler& masm, ValOperandId val) { + MOZ_ASSERT(!addedFailurePath_); + OperandLocation& loc = operandLocations_[val.id()]; MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized); ValueOperand reg = allocateValueRegister(masm); loc.setValueReg(reg); return reg; } @@ -304,16 +312,18 @@ CacheRegisterAllocator::discardStack(Mac } freePayloadSlots_.clear(); freeValueSlots_.clear(); } Register CacheRegisterAllocator::allocateRegister(MacroAssembler& masm) { + MOZ_ASSERT(!addedFailurePath_); + if (availableRegs_.empty()) freeDeadOperandLocations(masm); if (availableRegs_.empty()) { // Still no registers available, try to spill unused operands to // the stack. for (size_t i = 0; i < operandLocations_.length(); i++) { OperandLocation& loc = operandLocations_[i]; @@ -354,16 +364,18 @@ CacheRegisterAllocator::allocateRegister Register reg = availableRegs_.takeAny(); currentOpRegs_.add(reg); return reg; } void CacheRegisterAllocator::allocateFixedRegister(MacroAssembler& masm, Register reg) { + MOZ_ASSERT(!addedFailurePath_); + // Fixed registers should be allocated first, to ensure they're // still available. MOZ_ASSERT(!currentOpRegs_.has(reg), "Register is in use"); freeDeadOperandLocations(masm); if (availableRegs_.has(reg)) { availableRegs_.take(reg); @@ -474,16 +486,20 @@ CacheRegisterAllocator::fixupAliasedInpu spillOperandToStack(masm, &loc2); } else { MOZ_ASSERT(loc1.kind() == OperandLocation::PayloadReg); spillOperandToStack(masm, &loc1); break; // Spilled loc1, so nothing else will alias it. } } } + +#ifdef DEBUG + assertValidState(); +#endif } GeneralRegisterSet CacheRegisterAllocator::inputRegisterSet() const { MOZ_ASSERT(origInputLocations_.length() == writer_.numInputOperands()); AllocatableGeneralRegisterSet result; @@ -663,16 +679,42 @@ CacheRegisterAllocator::popValue(MacroAs MOZ_ASSERT(loc->valueStack() < stackPushed_); masm.loadValue(Address(masm.getStackPointer(), stackPushed_ - loc->valueStack()), dest); masm.propagateOOM(freeValueSlots_.append(loc->valueStack())); } loc->setValueReg(dest); } +#ifdef DEBUG +void +CacheRegisterAllocator::assertValidState() const +{ + // Assert different operands don't have aliasing storage. We depend on this + // when spilling registers, for instance. + + if (!JitOptions.fullDebugChecks) + return; + + for (size_t i = 0; i < operandLocations_.length(); i++) { + const auto& loc1 = operandLocations_[i]; + if (loc1.isUninitialized()) + continue; + + for (size_t j = 0; j < i; j++) { + const auto& loc2 = operandLocations_[j]; + if (loc2.isUninitialized()) + continue; + MOZ_ASSERT(loc1 != loc2); + MOZ_ASSERT(!loc1.aliasesReg(loc2)); + } + } +} +#endif + bool OperandLocation::aliasesReg(const OperandLocation& other) const { MOZ_ASSERT(&other != this); switch (other.kind_) { case PayloadReg: return aliasesReg(other.payloadReg()); @@ -1160,16 +1202,20 @@ FailurePath::canShareFailurePath(const F return false; } return true; } bool CacheIRCompiler::addFailurePath(FailurePath** failure) { +#ifdef DEBUG + allocator.setAddedFailurePath(); +#endif + FailurePath newFailure; for (size_t i = 0; i < writer_.numInputOperands(); i++) { if (!newFailure.appendInput(allocator.operandLocation(i))) return false; } if (!newFailure.setSpilledRegs(allocator.spilledRegs())) return false; newFailure.setStackPushed(allocator.stackPushed());
--- a/js/src/jit/CacheIRCompiler.h +++ b/js/src/jit/CacheIRCompiler.h @@ -206,16 +206,17 @@ class OperandLocation kind_ = Constant; data_.constant = v; } void setBaselineFrame(BaselineFrameSlot slot) { kind_ = BaselineFrame; data_.baselineFrameSlot = slot; } + bool isUninitialized() const { return kind_ == Uninitialized; } bool isInRegister() const { return kind_ == PayloadReg || kind_ == ValueReg; } bool isOnStack() const { return kind_ == PayloadStack || kind_ == ValueStack; } size_t stackPushed() const { if (kind_ == PayloadStack) return data_.payloadStack.stackPushed; MOZ_ASSERT(kind_ == ValueStack); return data_.valueStackPushed; @@ -300,39 +301,52 @@ class MOZ_RAII CacheRegisterAllocator AllocatableGeneralRegisterSet availableRegsAfterSpill_; // Registers we took from availableRegsAfterSpill_ and spilled to the stack. SpilledRegisterVector spilledRegs_; // The number of bytes pushed on the native stack. uint32_t stackPushed_; +#ifdef DEBUG + // Flag used to assert individual CacheIR instructions don't allocate + // registers after calling addFailurePath. + bool addedFailurePath_; +#endif + // The index of the CacheIR instruction we're currently emitting. uint32_t currentInstruction_; const CacheIRWriter& writer_; CacheRegisterAllocator(const CacheRegisterAllocator&) = delete; CacheRegisterAllocator& operator=(const CacheRegisterAllocator&) = delete; void freeDeadOperandLocations(MacroAssembler& masm); void spillOperandToStack(MacroAssembler& masm, OperandLocation* loc); void spillOperandToStackOrRegister(MacroAssembler& masm, OperandLocation* loc); void popPayload(MacroAssembler& masm, OperandLocation* loc, Register dest); void popValue(MacroAssembler& masm, OperandLocation* loc, ValueOperand dest); +#ifdef DEBUG + void assertValidState() const; +#endif + public: friend class AutoScratchRegister; friend class AutoScratchRegisterExcluding; explicit CacheRegisterAllocator(const CacheIRWriter& writer) : allocatableRegs_(GeneralRegisterSet::All()), stackPushed_(0), +#ifdef DEBUG + addedFailurePath_(false), +#endif currentInstruction_(0), writer_(writer) {} MOZ_MUST_USE bool init(); void initAvailableRegs(const AllocatableGeneralRegisterSet& available) { availableRegs_ = available; @@ -378,20 +392,31 @@ class MOZ_RAII CacheRegisterAllocator const SpilledRegisterVector& spilledRegs() const { return spilledRegs_; } MOZ_MUST_USE bool setSpilledRegs(const SpilledRegisterVector& regs) { spilledRegs_.clear(); return spilledRegs_.appendAll(regs); } void nextOp() { +#ifdef DEBUG + assertValidState(); + addedFailurePath_ = false; +#endif currentOpRegs_.clear(); currentInstruction_++; } +#ifdef DEBUG + void setAddedFailurePath() { + MOZ_ASSERT(!addedFailurePath_, "multiple failure paths for instruction"); + addedFailurePath_ = true; + } +#endif + bool isDeadAfterInstruction(OperandId opId) const { return writer_.operandIsDead(opId.id(), currentInstruction_ + 1); } uint32_t stackPushed() const { return stackPushed_; } void setStackPushed(uint32_t pushed) { @@ -531,25 +556,26 @@ class FailurePath // be emitted for two failure paths, so we can share them. bool canShareFailurePath(const FailurePath& other) const; }; /** * Wrap an offset so that a call can decide to embed a constant * or load from the stub data. */ -class StubFieldOffset { +class StubFieldOffset +{ private: uint32_t offset_; StubField::Type type_; public: StubFieldOffset(uint32_t offset, StubField::Type type) : offset_(offset), type_(type) - { } + { } uint32_t getOffset() { return offset_; } StubField::Type getStubFieldType() { return type_; } }; class AutoOutputRegister; // Base class for BaselineCacheIRCompiler and IonCacheIRCompiler.
--- a/js/src/wasm/WasmTypes.cpp +++ b/js/src/wasm/WasmTypes.cpp @@ -642,16 +642,19 @@ DebugFrame::getLocal(uint32_t localIndex vp.set(NumberValue((double)*static_cast<int64_t*>(dataPtr))); break; case jit::MIRType::Float32: vp.set(NumberValue(JS::CanonicalizeNaN(*static_cast<float*>(dataPtr)))); break; case jit::MIRType::Double: vp.set(NumberValue(JS::CanonicalizeNaN(*static_cast<double*>(dataPtr)))); break; + case jit::MIRType::Pointer: + vp.set(ObjectOrNullValue(*(JSObject**)dataPtr)); + break; default: MOZ_CRASH("local type"); } return true; } void DebugFrame::updateReturnJSValue() @@ -670,16 +673,19 @@ DebugFrame::updateReturnJSValue() cachedReturnJSValue_.setDouble((double)resultI64_); break; case ExprType::F32: cachedReturnJSValue_.setDouble(JS::CanonicalizeNaN(resultF32_)); break; case ExprType::F64: cachedReturnJSValue_.setDouble(JS::CanonicalizeNaN(resultF64_)); break; + case ExprType::AnyRef: + cachedReturnJSValue_ = ObjectOrNullValue(*(JSObject**)&resultRef_); + break; default: MOZ_CRASH("result type"); } } HandleValue DebugFrame::returnValue() const {
--- a/js/src/wasm/WasmTypes.h +++ b/js/src/wasm/WasmTypes.h @@ -1956,20 +1956,21 @@ static_assert(sizeof(Frame) % 16 == 0, " class DebugFrame { // The results field left uninitialized and only used during the baseline // compiler's return sequence to allow the debugger to inspect and modify // the return value of a frame being debugged. union { - int32_t resultI32_; - int64_t resultI64_; - float resultF32_; - double resultF64_; + int32_t resultI32_; + int64_t resultI64_; + intptr_t resultRef_; + float resultF32_; + double resultF64_; }; // The returnValue() method returns a HandleValue pointing to this field. js::Value cachedReturnJSValue_; // The function index of this frame. Technically, this could be derived // given a PC into this frame (which could lookup the CodeRange which has // the function index), but this isn't always readily available.
--- a/js/xpconnect/idl/nsIXPCScriptable.idl +++ b/js/xpconnect/idl/nsIXPCScriptable.idl @@ -44,20 +44,20 @@ interface nsIXPConnectWrappedNative; #define XPC_SCRIPTABLE_WANT_FINALIZE (1 << 6) #define XPC_SCRIPTABLE_WANT_CALL (1 << 7) #define XPC_SCRIPTABLE_WANT_CONSTRUCT (1 << 8) #define XPC_SCRIPTABLE_WANT_HASINSTANCE (1 << 9) #define XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY (1 << 10) #define XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY (1 << 11) // (1 << 12) is unused #define XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE (1 << 13) - #define XPC_SCRIPTABLE_DONT_ASK_INSTANCE_FOR_SCRIPTABLE (1 << 14) - #define XPC_SCRIPTABLE_CLASSINFO_INTERFACES_ONLY (1 << 15) + // (1 << 14) is unused + // (1 << 15) is unused #define XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE (1 << 16) - #define XPC_SCRIPTABLE_ALLOW_PROP_MODS_TO_PROTOTYPE (1 << 17) + // (1 << 17) is unused #define XPC_SCRIPTABLE_IS_GLOBAL_OBJECT (1 << 18) #define XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES (1 << 19) %} /** * Note: This is not really an XPCOM interface. For example, callers must * guarantee that they set the *_retval of the various methods that return a * boolean to PR_TRUE before making the call. Implementations may skip writing @@ -95,18 +95,16 @@ interface nsIXPCScriptable : nsISupports boolean construct(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSCallArgsRef args); boolean hasInstance(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out boolean bp); - void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto); - %{ C++ #define GET_IT(f_, c_) \ bool f_() { \ return 0 != (GetScriptableFlags() & XPC_SCRIPTABLE_##c_); \ } GET_IT(WantPreCreate, WANT_PRECREATE) GET_IT(WantEnumerate, WANT_ENUMERATE) @@ -114,51 +112,15 @@ interface nsIXPCScriptable : nsISupports GET_IT(WantResolve, WANT_RESOLVE) GET_IT(WantFinalize, WANT_FINALIZE) GET_IT(WantCall, WANT_CALL) GET_IT(WantConstruct, WANT_CONSTRUCT) GET_IT(WantHasInstance, WANT_HASINSTANCE) GET_IT(UseJSStubForAddProperty, USE_JSSTUB_FOR_ADDPROPERTY) GET_IT(UseJSStubForDelProperty, USE_JSSTUB_FOR_DELPROPERTY) GET_IT(DontEnumQueryInterface, DONT_ENUM_QUERY_INTERFACE) - GET_IT(DontAskInstanceForScriptable, DONT_ASK_INSTANCE_FOR_SCRIPTABLE) - GET_IT(ClassInfoInterfacesOnly, CLASSINFO_INTERFACES_ONLY) GET_IT(AllowPropModsDuringResolve, ALLOW_PROP_MODS_DURING_RESOLVE) - GET_IT(AllowPropModsToPrototype, ALLOW_PROP_MODS_TO_PROTOTYPE) GET_IT(IsGlobalObject, IS_GLOBAL_OBJECT) GET_IT(DontReflectInterfaceNames, DONT_REFLECT_INTERFACE_NAMES) #undef GET_IT %} }; - -%{ C++ - -#include "nsAutoPtr.h" - -#define NS_XPCCLASSINFO_IID \ -{ 0x43b67f01, 0xd4ce, 0x4b82, \ - { 0xb3, 0xf8, 0xeb, 0xf2, 0x13, 0x60, 0xfb, 0x7e } } - -class NS_NO_VTABLE nsXPCClassInfo : public nsIClassInfo, - public nsIXPCScriptable -{ -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_XPCCLASSINFO_IID) - - NS_IMETHOD_(MozExternalRefCountType) AddRef() override = 0; - NS_IMETHOD_(MozExternalRefCountType) Release() override = 0; - - virtual void PreserveWrapper(nsISupports *aNative) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsXPCClassInfo, NS_XPCCLASSINFO_IID) - -inline -nsresult -CallQueryInterface(nsISupports* aSourcePtr, - RefPtrGetterAddRefs<nsXPCClassInfo> aDestPtr) -{ - return CallQueryInterface(aSourcePtr, - static_cast<nsXPCClassInfo**>(aDestPtr)); -} - -%}
--- a/js/xpconnect/public/xpc_map_end.h +++ b/js/xpconnect/public/xpc_map_end.h @@ -94,16 +94,13 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::Constru {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;} #endif #if !((XPC_MAP_FLAGS) & XPC_SCRIPTABLE_WANT_HASINSTANCE) NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative* wrapper, JSContext * cx, JSObject * obj, JS::HandleValue val, bool* bp, bool* _retval) {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;} #endif -NS_IMETHODIMP XPC_MAP_CLASSNAME::PostCreatePrototype(JSContext* cx, JSObject* proto) - {return NS_OK;} - /**************************************************************/ #undef XPC_MAP_CLASSNAME #undef XPC_MAP_QUOTED_CLASSNAME #undef XPC_MAP_FLAGS
--- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -2915,17 +2915,17 @@ XPCJSRuntime::InitializeStrings(JSContex return true; } bool XPCJSRuntime::DescribeCustomObjects(JSObject* obj, const js::Class* clasp, char (&name)[72]) const { - if (!IS_PROTO_CLASS(clasp)) { + if (clasp != &XPC_WN_Proto_JSClass) { return false; } XPCWrappedNativeProto* p = static_cast<XPCWrappedNativeProto*>(xpc_GetJSPrivate(obj)); nsCOMPtr<nsIXPCScriptable> scr = p->GetScriptable(); if (!scr) { return false;
--- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -151,17 +151,17 @@ FinishCreate(XPCWrappedNativeScope* Scop nsresult XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper, nsIPrincipal* principal, bool initStandardClasses, JS::CompartmentOptions& aOptions, XPCWrappedNative** wrappedGlobal) { AutoJSContext cx; - nsISupports* identity = nativeHelper.GetCanonical(); + nsCOMPtr<nsISupports> identity = do_QueryInterface(nativeHelper.Object()); // The object should specify that it's meant to be global. MOZ_ASSERT(nativeHelper.GetScriptableFlags() & XPC_SCRIPTABLE_IS_GLOBAL_OBJECT); // We shouldn't be reusing globals. MOZ_ASSERT(!nativeHelper.GetWrapperCache() || !nativeHelper.GetWrapperCache()->GetWrapperPreserveColor()); @@ -193,32 +193,30 @@ XPCWrappedNative::WrapNewGlobal(xpcObjec // If requested, initialize the standard classes on the global. if (initStandardClasses && ! JS_InitStandardClasses(cx, global)) return NS_ERROR_FAILURE; // Make a proto. XPCWrappedNativeProto* proto = XPCWrappedNativeProto::GetNewOrUsed(scope, nativeHelper.GetClassInfo(), - scrProto, - /* callPostCreatePrototype = */ false); + scrProto); if (!proto) return NS_ERROR_FAILURE; // Set up the prototype on the global. MOZ_ASSERT(proto->GetJSProtoObject()); RootedObject protoObj(cx, proto->GetJSProtoObject()); bool success = JS_SplicePrototype(cx, global, protoObj); if (!success) return NS_ERROR_FAILURE; // Construct the wrapper, which takes over the strong reference to the // native object. - RefPtr<XPCWrappedNative> wrapper = - new XPCWrappedNative(nativeHelper.forgetCanonical(), proto); + RefPtr<XPCWrappedNative> wrapper = new XPCWrappedNative(identity.forget(), proto); // // We don't call ::Init() on this wrapper, because our setup requirements // are different for globals. We do our setup inline here, instead. // wrapper->mScriptable = scrWrapper; @@ -279,17 +277,17 @@ XPCWrappedNative::GetNewOrUsed(xpcObject "We assume the caller already checked if it could get the " "wrapper from the cache."); nsresult rv; MOZ_ASSERT(!Scope->GetRuntime()->GCIsRunning(), "XPCWrappedNative::GetNewOrUsed called during GC"); - nsISupports* identity = helper.GetCanonical(); + nsCOMPtr<nsISupports> identity = do_QueryInterface(helper.Object()); if (!identity) { NS_ERROR("This XPCOM object fails in QueryInterface to nsISupports!"); return NS_ERROR_FAILURE; } RefPtr<XPCWrappedNative> wrapper; @@ -401,31 +399,30 @@ XPCWrappedNative::GetNewOrUsed(xpcObject // Note that the security check happens inside FindTearOff - after the // wrapper is actually created, but before JS code can see it. if (info && !isClassInfoSingleton) { proto = XPCWrappedNativeProto::GetNewOrUsed(Scope, info, scrProto); if (!proto) return NS_ERROR_FAILURE; - wrapper = new XPCWrappedNative(helper.forgetCanonical(), proto); + wrapper = new XPCWrappedNative(identity.forget(), proto); } else { RefPtr<XPCNativeInterface> iface = Interface; if (!iface) iface = XPCNativeInterface::GetISupports(); XPCNativeSetKey key(iface); RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(&key); if (!set) return NS_ERROR_FAILURE; - wrapper = new XPCWrappedNative(helper.forgetCanonical(), Scope, - set.forget()); + wrapper = new XPCWrappedNative(identity.forget(), Scope, set.forget()); } MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(parent), "Xray wrapper being used to parent XPCWrappedNative?"); // We use an AutoMarkingPtr here because it is possible for JS gc to happen // after we have Init'd the wrapper but *before* we add it to the hashtable. // This would cause the mSet to get collected and we'd later crash. I've @@ -545,24 +542,16 @@ XPCWrappedNative::Destroy() // This is factored out so that it can be called publicly. // static nsIXPCScriptable* XPCWrappedNative::GatherProtoScriptable(nsIClassInfo* classInfo) { MOZ_ASSERT(classInfo, "bad param"); - nsXPCClassInfo* classInfoHelper = nullptr; - CallQueryInterface(classInfo, &classInfoHelper); - if (classInfoHelper) { - nsCOMPtr<nsIXPCScriptable> helper = - dont_AddRef(static_cast<nsIXPCScriptable*>(classInfoHelper)); - return helper; - } - nsCOMPtr<nsIXPCScriptable> helper; nsresult rv = classInfo->GetScriptableHelper(getter_AddRefs(helper)); if (NS_SUCCEEDED(rv) && helper) { return helper; } return nullptr; } @@ -578,23 +567,16 @@ XPCWrappedNative::GatherScriptable(nsISu MOZ_ASSERT(!*aScrWrapper, "bad param"); nsCOMPtr<nsIXPCScriptable> scrProto; nsCOMPtr<nsIXPCScriptable> scrWrapper; // Get the class scriptable helper (if present) if (aClassInfo) { scrProto = GatherProtoScriptable(aClassInfo); - - if (scrProto && scrProto->DontAskInstanceForScriptable()) { - scrWrapper = scrProto; - scrProto.forget(aScrProto); - scrWrapper.forget(aScrWrapper); - return; - } } // Do the same for the wrapper specific scriptable scrWrapper = do_QueryInterface(aObj); if (scrWrapper) { // A whole series of assertions to catch bad uses of scriptable flags on // the scrWrapper... @@ -603,35 +585,20 @@ XPCWrappedNative::GatherScriptable(nsISu MOZ_ASSERT_IF(scrWrapper->WantPreCreate(), scrProto && scrProto->WantPreCreate()); // Can't set DONT_ENUM_QUERY_INTERFACE on an instance scriptable // without also setting it on the class scriptable (if present). MOZ_ASSERT_IF(scrWrapper->DontEnumQueryInterface() && scrProto, scrProto->DontEnumQueryInterface()); - // Can't set DONT_ASK_INSTANCE_FOR_SCRIPTABLE on an instance scriptable - // without also setting it on the class scriptable. - MOZ_ASSERT_IF(scrWrapper->DontAskInstanceForScriptable(), - scrProto && scrProto->DontAskInstanceForScriptable()); - - // Can't set CLASSINFO_INTERFACES_ONLY on an instance scriptable - // without also setting it on the class scriptable (if present). - MOZ_ASSERT_IF(scrWrapper->ClassInfoInterfacesOnly() && scrProto, - scrProto->ClassInfoInterfacesOnly()); - // Can't set ALLOW_PROP_MODS_DURING_RESOLVE on an instance scriptable // without also setting it on the class scriptable (if present). MOZ_ASSERT_IF(scrWrapper->AllowPropModsDuringResolve() && scrProto, scrProto->AllowPropModsDuringResolve()); - - // Can't set ALLOW_PROP_MODS_TO_PROTOTYPE on an instance scriptable - // without also setting it on the class scriptable (if present). - MOZ_ASSERT_IF(scrWrapper->AllowPropModsToPrototype() && scrProto, - scrProto->AllowPropModsToPrototype()); } else { scrWrapper = scrProto; } scrProto.forget(aScrProto); scrWrapper.forget(aScrWrapper); } @@ -988,25 +955,16 @@ XPCWrappedNative::InitTearOff(XPCWrapped const nsIID* iid = aInterface->GetIID(); nsISupports* identity = GetIdentityObject(); // This is an nsRefPtr instead of an nsCOMPtr because it may not be the // canonical nsISupports for this object. RefPtr<nsISupports> qiResult; - // If the scriptable helper forbids us from reflecting additional - // interfaces, then don't even try the QI, just fail. - if (mScriptable && - mScriptable->ClassInfoInterfacesOnly() && - !mSet->HasInterface(aInterface) && - !mSet->HasInterfaceWithAncestor(aInterface)) { - return NS_ERROR_NO_INTERFACE; - } - // We are about to call out to other code. // So protect our intended tearoff. aTearOff->SetReserved(); if (NS_FAILED(identity->QueryInterface(*iid, getter_AddRefs(qiResult))) || !qiResult) { aTearOff->SetInterface(nullptr); return NS_ERROR_NO_INTERFACE;
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp +++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp @@ -247,28 +247,16 @@ DefinePropertyIfFound(XPCCallContext& cc else found = set->FindMember(id, &member, &iface); } else found = (nullptr != (member = iface->FindMember(id))); if (!found) { if (reflectToStringAndToSource) { JSNative call; - uint32_t flags = 0; - - if (scr) { - nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(scr); - - if (classInfo) { - nsresult rv = classInfo->GetFlags(&flags); - if (NS_FAILED(rv)) - return Throw(rv, ccx); - } - } - if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING)) { call = XPC_WN_Shared_ToString; name = xpccx->GetStringName(XPCJSContext::IDX_TO_STRING); } else if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_SOURCE)) { call = XPC_WN_Shared_ToSource; name = xpccx->GetStringName(XPCJSContext::IDX_TO_SOURCE); } else if (id == SYMBOL_TO_JSID( JS::GetWellKnownSymbol(ccx, JS::SymbolCode::toPrimitive))) @@ -947,20 +935,19 @@ XPC_WN_GetterSetter(JSContext* cx, unsig ccx.SetCallInfo(iface, member, false); return XPCWrappedNative::GetAttribute(ccx); } /***************************************************************************/ static bool -XPC_WN_Shared_Proto_Enumerate(JSContext* cx, HandleObject obj) +XPC_WN_Proto_Enumerate(JSContext* cx, HandleObject obj) { - MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_Proto_JSClass || - js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass, + MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass, "bad proto"); XPCWrappedNativeProto* self = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); if (!self) return false; XPCNativeSet* set = self->GetSet(); if (!set) @@ -981,106 +968,53 @@ XPC_WN_Shared_Proto_Enumerate(JSContext* return false; } } return true; } static void -XPC_WN_Shared_Proto_Finalize(js::FreeOp* fop, JSObject* obj) +XPC_WN_Proto_Finalize(js::FreeOp* fop, JSObject* obj) { // This can be null if xpc shutdown has already happened XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); if (p) p->JSProtoObjectFinalized(fop, obj); } static size_t -XPC_WN_Shared_Proto_ObjectMoved(JSObject* obj, JSObject* old) +XPC_WN_Proto_ObjectMoved(JSObject* obj, JSObject* old) { // This can be null if xpc shutdown has already happened XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); if (!p) return 0; p->JSProtoObjectMoved(obj, old); return 0; } static void -XPC_WN_Shared_Proto_Trace(JSTracer* trc, JSObject* obj) +XPC_WN_Proto_Trace(JSTracer* trc, JSObject* obj) { // This can be null if xpc shutdown has already happened XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); if (p) p->TraceInside(trc); } /*****************************************************/ static bool -XPC_WN_ModsAllowed_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvep) -{ - MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_Proto_JSClass, - "bad proto"); - - XPCWrappedNativeProto* self = - (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); - if (!self) - return false; - - XPCCallContext ccx(cx); - if (!ccx.IsValid()) - return false; - - nsCOMPtr<nsIXPCScriptable> scr = self->GetScriptable(); - return DefinePropertyIfFound(ccx, obj, id, - self->GetSet(), nullptr, nullptr, - self->GetScope(), - true, nullptr, nullptr, scr, - JSPROP_ENUMERATE, resolvep); -} - -static const js::ClassOps XPC_WN_ModsAllowed_Proto_JSClassOps = { - nullptr, // addProperty - nullptr, // delProperty - XPC_WN_Shared_Proto_Enumerate, // enumerate - nullptr, // newEnumerate - XPC_WN_ModsAllowed_Proto_Resolve, // resolve - nullptr, // mayResolve - XPC_WN_Shared_Proto_Finalize, // finalize - nullptr, // call - nullptr, // construct - nullptr, // hasInstance - XPC_WN_Shared_Proto_Trace, // trace -}; - -static const js::ClassExtension XPC_WN_Shared_Proto_ClassExtension = { - nullptr, /* weakmapKeyDelegateOp */ - XPC_WN_Shared_Proto_ObjectMoved -}; - -const js::Class XPC_WN_ModsAllowed_Proto_JSClass = { - "XPC_WN_ModsAllowed_Proto_JSClass", - XPC_WRAPPER_FLAGS, - &XPC_WN_ModsAllowed_Proto_JSClassOps, - JS_NULL_CLASS_SPEC, - &XPC_WN_Shared_Proto_ClassExtension, - JS_NULL_OBJECT_OPS -}; - -/***************************************************************************/ - -static bool XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleId id, HandleValue v) { - MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass, + MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass, "bad proto"); XPCWrappedNativeProto* self = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); if (!self) return false; XPCCallContext ccx(cx); @@ -1090,19 +1024,19 @@ XPC_WN_OnlyIWrite_Proto_AddPropertyStub( // Allow XPConnect to add the property only if (ccx.GetResolveName() == id) return true; return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); } static bool -XPC_WN_NoMods_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) +XPC_WN_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) { - MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass, + MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass, "bad proto"); XPCWrappedNativeProto* self = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); if (!self) return false; XPCCallContext ccx(cx); @@ -1115,36 +1049,41 @@ XPC_WN_NoMods_Proto_Resolve(JSContext* c self->GetSet(), nullptr, nullptr, self->GetScope(), true, nullptr, nullptr, scr, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE, resolvedp); } -static const js::ClassOps XPC_WN_NoMods_Proto_JSClassOps = { +static const js::ClassOps XPC_WN_Proto_JSClassOps = { XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty XPC_WN_CannotDeletePropertyStub, // delProperty - XPC_WN_Shared_Proto_Enumerate, // enumerate + XPC_WN_Proto_Enumerate, // enumerate nullptr, // newEnumerate - XPC_WN_NoMods_Proto_Resolve, // resolve + XPC_WN_Proto_Resolve, // resolve nullptr, // mayResolve - XPC_WN_Shared_Proto_Finalize, // finalize + XPC_WN_Proto_Finalize, // finalize nullptr, // call nullptr, // construct nullptr, // hasInstance - XPC_WN_Shared_Proto_Trace, // trace + XPC_WN_Proto_Trace, // trace }; -const js::Class XPC_WN_NoMods_Proto_JSClass = { - "XPC_WN_NoMods_Proto_JSClass", +static const js::ClassExtension XPC_WN_Proto_ClassExtension = { + nullptr, /* weakmapKeyDelegateOp */ + XPC_WN_Proto_ObjectMoved +}; + +const js::Class XPC_WN_Proto_JSClass = { + "XPC_WN_Proto_JSClass", XPC_WRAPPER_FLAGS, - &XPC_WN_NoMods_Proto_JSClassOps, + &XPC_WN_Proto_JSClassOps, JS_NULL_CLASS_SPEC, - &XPC_WN_Shared_Proto_ClassExtension, + &XPC_WN_Proto_ClassExtension, JS_NULL_OBJECT_OPS }; /***************************************************************************/ static bool XPC_WN_TearOff_Enumerate(JSContext* cx, HandleObject obj) {
--- a/js/xpconnect/src/XPCWrappedNativeProto.cpp +++ b/js/xpconnect/src/XPCWrappedNativeProto.cpp @@ -45,64 +45,34 @@ XPCWrappedNativeProto::~XPCWrappedNative #endif // Note that our weak ref to mScope is not to be trusted at this point. XPCNativeSet::ClearCacheEntryForClassInfo(mClassInfo); } bool -XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable, - bool callPostCreatePrototype) +XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable) { AutoJSContext cx; mScriptable = scriptable; - const js::Class* jsclazz = - (mScriptable && mScriptable->AllowPropModsToPrototype()) - ? &XPC_WN_ModsAllowed_Proto_JSClass - : &XPC_WN_NoMods_Proto_JSClass; - JS::RootedObject global(cx, mScope->GetGlobalJSObject()); JS::RootedObject proto(cx, JS_GetObjectPrototype(cx, global)); - mJSProtoObject = JS_NewObjectWithUniqueType(cx, js::Jsvalify(jsclazz), + mJSProtoObject = JS_NewObjectWithUniqueType(cx, js::Jsvalify(&XPC_WN_Proto_JSClass), proto); bool success = !!mJSProtoObject; if (success) { JS_SetPrivate(mJSProtoObject, this); - if (callPostCreatePrototype) - success = CallPostCreatePrototype(); } return success; } -bool -XPCWrappedNativeProto::CallPostCreatePrototype() -{ - AutoJSContext cx; - - // Nothing to do if we don't have a scriptable callback. - if (!mScriptable) - return true; - - // Call the helper. This can handle being called if it's not implemented, - // so we don't have to check any sort of "want" here. See xpc_map_end.h. - nsresult rv = mScriptable->PostCreatePrototype(cx, mJSProtoObject); - if (NS_FAILED(rv)) { - JS_SetPrivate(mJSProtoObject, nullptr); - mJSProtoObject = nullptr; - XPCThrower::Throw(rv, cx); - return false; - } - - return true; -} - void XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj) { MOZ_ASSERT(obj == mJSProtoObject, "huh?"); #ifdef DEBUG // Check that this object has already been swept from the map. ClassInfo2WrappedNativeProtoMap* map = GetScope()->GetWrappedNativeProtoMap(); @@ -133,18 +103,17 @@ XPCWrappedNativeProto::SystemIsBeingShut mJSProtoObject = nullptr; } } // static XPCWrappedNativeProto* XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope, nsIClassInfo* classInfo, - nsIXPCScriptable* scriptable, - bool callPostCreatePrototype) + nsIXPCScriptable* scriptable) { AutoJSContext cx; MOZ_ASSERT(scope, "bad param"); MOZ_ASSERT(classInfo, "bad param"); AutoMarkingWrappedNativeProtoPtr proto(cx); ClassInfo2WrappedNativeProtoMap* map = nullptr; @@ -154,17 +123,17 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCW return proto; RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(classInfo); if (!set) return nullptr; proto = new XPCWrappedNativeProto(scope, classInfo, set.forget()); - if (!proto || !proto->Init(scriptable, callPostCreatePrototype)) { + if (!proto || !proto->Init(scriptable)) { delete proto.get(); return nullptr; } map->Add(classInfo, proto); return proto; }
--- a/js/xpconnect/src/moz.build +++ b/js/xpconnect/src/moz.build @@ -1,17 +1,16 @@ # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # 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/. EXPORTS += [ 'BackstagePass.h', - 'qsObjectHelper.h', 'XPCJSMemoryReporter.h', 'xpcObjectHelper.h', 'xpcpublic.h', ] UNIFIED_SOURCES += [ 'ExportHelpers.cpp', 'nsXPConnect.cpp',
deleted file mode 100644 --- a/js/xpconnect/src/qsObjectHelper.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=99: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. */ - -#ifndef qsObjectHelper_h -#define qsObjectHelper_h - -#include "xpcObjectHelper.h" - -#include "nsCOMPtr.h" -#include "nsWrapperCache.h" -#include "mozilla/TypeTraits.h" - -class qsObjectHelper : public xpcObjectHelper -{ -public: - template <class T> - inline - qsObjectHelper(T* aObject, nsWrapperCache* aCache) - : xpcObjectHelper(ToSupports(aObject), ToCanonicalSupports(aObject), - aCache) - {} - - template <class T> - inline - qsObjectHelper(nsCOMPtr<T>& aObject, nsWrapperCache* aCache) - : xpcObjectHelper(ToSupports(aObject.get()), - ToCanonicalSupports(aObject.get()), aCache) - { - if (mCanonical) { - // Transfer the strong reference. - mCanonicalStrong = dont_AddRef(mCanonical); - aObject.forget(); - } - } - - template <class T> - inline - qsObjectHelper(RefPtr<T>& aObject, nsWrapperCache* aCache) - : xpcObjectHelper(ToSupports(aObject.get()), - ToCanonicalSupports(aObject.get()), aCache) - { - if (mCanonical) { - // Transfer the strong reference. - mCanonicalStrong = dont_AddRef(mCanonical); - aObject.forget(); - } - } -}; - -#endif
--- a/js/xpconnect/src/xpcObjectHelper.h +++ b/js/xpconnect/src/xpcObjectHelper.h @@ -21,117 +21,56 @@ #include "nsISupports.h" #include "nsIXPCScriptable.h" #include "nsWrapperCache.h" class xpcObjectHelper { public: explicit xpcObjectHelper(nsISupports* aObject, nsWrapperCache* aCache = nullptr) - : mCanonical(nullptr) - , mObject(aObject) + : mObject(aObject) , mCache(aCache) { - if (!mCache) { - if (aObject) - CallQueryInterface(aObject, &mCache); - else - mCache = nullptr; + if (!mCache && aObject) { + CallQueryInterface(aObject, &mCache); } } nsISupports* Object() { return mObject; } - nsISupports* GetCanonical() - { - if (!mCanonical) { - mCanonicalStrong = do_QueryInterface(mObject); - mCanonical = mCanonicalStrong; - } - return mCanonical; - } - - already_AddRefed<nsISupports> forgetCanonical() - { - MOZ_ASSERT(mCanonical, "Huh, no canonical to forget?"); - - if (!mCanonicalStrong) - mCanonicalStrong = mCanonical; - mCanonical = nullptr; - return mCanonicalStrong.forget(); - } - nsIClassInfo* GetClassInfo() { - if (mXPCClassInfo) - return mXPCClassInfo; if (!mClassInfo) mClassInfo = do_QueryInterface(mObject); return mClassInfo; } - nsXPCClassInfo* GetXPCClassInfo() - { - if (!mXPCClassInfo) { - CallQueryInterface(mObject, getter_AddRefs(mXPCClassInfo)); - } - return mXPCClassInfo; - } - - already_AddRefed<nsXPCClassInfo> forgetXPCClassInfo() - { - GetXPCClassInfo(); - - return mXPCClassInfo.forget(); - } // We assert that we can reach an nsIXPCScriptable somehow. uint32_t GetScriptableFlags() { - // Try getting an nsXPCClassInfo - this handles DOM scriptable helpers. - nsCOMPtr<nsIXPCScriptable> sinfo = GetXPCClassInfo(); - - // If that didn't work, try just QI-ing. This handles BackstagePass. - if (!sinfo) - sinfo = do_QueryInterface(GetCanonical()); + nsCOMPtr<nsIXPCScriptable> sinfo = do_QueryInterface(mObject); // We should have something by now. MOZ_ASSERT(sinfo); // Grab the flags. return sinfo->GetScriptableFlags(); } nsWrapperCache* GetWrapperCache() { return mCache; } -protected: - xpcObjectHelper(nsISupports* aObject, nsISupports* aCanonical, - nsWrapperCache* aCache) - : mCanonical(aCanonical) - , mObject(aObject) - , mCache(aCache) - { - if (!mCache && aObject) - CallQueryInterface(aObject, &mCache); - } - - nsCOMPtr<nsISupports> mCanonicalStrong; - nsISupports* MOZ_UNSAFE_REF("xpcObjectHelper has been specifically optimized " - "to avoid unnecessary AddRefs and Releases. " - "(see bug 565742)") mCanonical; - private: xpcObjectHelper(xpcObjectHelper& aOther) = delete; nsISupports* MOZ_UNSAFE_REF("xpcObjectHelper has been specifically optimized " "to avoid unnecessary AddRefs and Releases. " "(see bug 565742)") mObject; nsWrapperCache* mCache; nsCOMPtr<nsIClassInfo> mClassInfo; - RefPtr<nsXPCClassInfo> mXPCClassInfo; }; #endif
--- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -779,38 +779,28 @@ private: * **************************************************************************** ***************************************************************************/ // These are the various JSClasses and callbacks whose use that required // visibility from more than one .cpp file. extern const js::Class XPC_WN_NoHelper_JSClass; -extern const js::Class XPC_WN_NoMods_Proto_JSClass; -extern const js::Class XPC_WN_ModsAllowed_Proto_JSClass; +extern const js::Class XPC_WN_Proto_JSClass; extern const js::Class XPC_WN_Tearoff_JSClass; #define XPC_WN_TEAROFF_RESERVED_SLOTS 1 #define XPC_WN_TEAROFF_FLAT_OBJECT_SLOT 0 extern const js::Class XPC_WN_NoHelper_Proto_JSClass; extern bool XPC_WN_CallMethod(JSContext* cx, unsigned argc, JS::Value* vp); extern bool XPC_WN_GetterSetter(JSContext* cx, unsigned argc, JS::Value* vp); -// Maybe this macro should check for class->enumerate == -// XPC_WN_Shared_Proto_Enumerate or something rather than checking for -// 4 classes? -static inline bool IS_PROTO_CLASS(const js::Class* clazz) -{ - return clazz == &XPC_WN_NoMods_Proto_JSClass || - clazz == &XPC_WN_ModsAllowed_Proto_JSClass; -} - /***************************************************************************/ // XPCWrappedNativeScope is one-to-one with a JS global object. class nsXPCComponentsBase; class XPCWrappedNativeScope final { public: @@ -1272,18 +1262,17 @@ class XPCNativeSet final // for XPCWrappedNative whose native objects expose nsIClassInfo. class XPCWrappedNativeProto final { public: static XPCWrappedNativeProto* GetNewOrUsed(XPCWrappedNativeScope* scope, nsIClassInfo* classInfo, - nsIXPCScriptable* scriptable, - bool callPostCreatePrototype = true); + nsIXPCScriptable* scriptable); XPCWrappedNativeScope* GetScope() const {return mScope;} XPCJSRuntime* GetRuntime() const {return mScope->GetRuntime();} JSObject* @@ -1296,17 +1285,16 @@ public: GetClassInfo() const {return mClassInfo;} XPCNativeSet* GetSet() const {return mSet;} nsIXPCScriptable* GetScriptable() const { return mScriptable; } - bool CallPostCreatePrototype(); void JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj); void JSProtoObjectMoved(JSObject* obj, const JSObject* old); void SystemIsBeingShutDown(); void DebugDump(int16_t depth); void TraceSelf(JSTracer* trc) { @@ -1340,17 +1328,17 @@ protected: XPCWrappedNativeProto(const XPCWrappedNativeProto& r) = delete; XPCWrappedNativeProto& operator= (const XPCWrappedNativeProto& r) = delete; // hide ctor XPCWrappedNativeProto(XPCWrappedNativeScope* Scope, nsIClassInfo* ClassInfo, already_AddRefed<XPCNativeSet>&& Set); - bool Init(nsIXPCScriptable* scriptable, bool callPostCreatePrototype); + bool Init(nsIXPCScriptable* scriptable); private: #ifdef DEBUG static int32_t gDEBUG_LiveProtoCount; #endif private: XPCWrappedNativeScope* mScope;
--- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -1446,21 +1446,16 @@ static bool IsWindow(JSContext* cx, JSObject* wrapper) { return !!AsWindow(cx, wrapper); } void XPCWrappedNativeXrayTraits::preserveWrapper(JSObject* target) { - XPCWrappedNative* wn = XPCWrappedNative::Get(target); - RefPtr<nsXPCClassInfo> ci; - CallQueryInterface(wn->Native(), getter_AddRefs(ci)); - if (ci) - ci->PreserveWrapper(wn->Native()); } static bool XrayToString(JSContext* cx, unsigned argc, JS::Value* vp); bool XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext* cx, HandleObject wrapper, HandleObject holder, HandleId id,
--- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -255,20 +255,12 @@ nsFrameManager::RestoreFrameState(nsIFra nsFrameList::Enumerator childFrames(lists.CurrentList()); for (; !childFrames.AtEnd(); childFrames.Next()) { RestoreFrameState(childFrames.get(), aState); } } } void -nsFrameManager::DestroyAnonymousContent(already_AddRefed<nsIContent> aContent) -{ - if (nsCOMPtr<nsIContent> content = aContent) { - content->UnbindFromTree(); - } -} - -void nsFrameManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const { aSizes.mLayoutPresShellSize += aSizes.mState.mMallocSizeOf(this); }
--- a/layout/base/nsFrameManager.h +++ b/layout/base/nsFrameManager.h @@ -88,18 +88,16 @@ public: /* * Add/restore state for one frame */ void CaptureFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState); void RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState); - void DestroyAnonymousContent(already_AddRefed<nsIContent> aContent); - void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const; protected: // weak link, because the pres shell owns us nsIPresShell* MOZ_NON_OWNING_REF mPresShell; nsIFrame* mRootFrame; };
--- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -446,16 +446,17 @@ nsTextControlFrame::InitializeEagerlyIfN } nsresult nsTextControlFrame::CreateRootNode() { MOZ_ASSERT(!mRootNode); mRootNode = CreateEmptyDiv(*this); + mRootNode->SetIsNativeAnonymousRoot(); mMutationObserver = new nsAnonDivObserver(*this); mRootNode->AddMutationObserver(mMutationObserver); // Make our root node editable mRootNode->SetFlags(NODE_IS_EDITABLE); // Set the necessary classes on the text control. We use class values instead
--- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -241,18 +241,20 @@ nsReflowStatus::UpdateTruncated(const Re mTruncated = false; } } /* static */ void nsIFrame::DestroyAnonymousContent(nsPresContext* aPresContext, already_AddRefed<nsIContent>&& aContent) { - aPresContext->PresShell()->FrameConstructor() - ->DestroyAnonymousContent(Move(aContent)); + if (nsCOMPtr<nsIContent> content = aContent) { + aPresContext->EventStateManager()->NativeAnonymousContentRemoved(content); + content->UnbindFromTree(); + } } // Formerly the nsIFrameDebug interface #ifdef DEBUG std::ostream& operator<<(std::ostream& aStream, const nsReflowStatus& aStatus) {
--- a/layout/style/CSSValue.h +++ b/layout/style/CSSValue.h @@ -4,39 +4,48 @@ * 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/. */ /* DOM object representing values in DOM computed style */ #ifndef mozilla_dom_CSSValue_h_ #define mozilla_dom_CSSValue_h_ -#include "nsWrapperCache.h" #include "nsStringFwd.h" +#include "mozilla/RefCounted.h" class nsROCSSPrimitiveValue; namespace mozilla { class ErrorResult; } // namespace mozilla namespace mozilla { namespace dom { /** * CSSValue - a DOM object representing values in DOM computed style. */ -class CSSValue : public nsISupports, - public nsWrapperCache +class CSSValue : public RefCounted<CSSValue> { public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(CSSValue); + enum : uint16_t { + CSS_INHERIT, + CSS_PRIMITIVE_VALUE, + CSS_VALUE_LIST, + CSS_CUSTOM, + }; + // CSSValue virtual void GetCssText(nsString& aText, mozilla::ErrorResult& aRv) = 0; virtual void SetCssText(const nsAString& aText, mozilla::ErrorResult& aRv) = 0; virtual uint16_t CssValueType() const = 0; + virtual ~CSSValue() { }; + // Downcasting /** * Return this as a nsROCSSPrimitiveValue* if its a primitive value, and null * otherwise. * * Defined in nsROCSSPrimitiveValue.h. */
--- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -8,17 +8,16 @@ #include "nsComputedDOMStyle.h" #include "mozilla/ArrayUtils.h" #include "mozilla/FontPropertyTypes.h" #include "mozilla/Preferences.h" #include "nsError.h" -#include "mozilla/dom/CSSPrimitiveValueBinding.h" #include "nsIFrame.h" #include "nsIFrameInlines.h" #include "mozilla/ComputedStyle.h" #include "nsIScrollableFrame.h" #include "nsContentUtils.h" #include "nsIContent.h" #include "nsDOMCSSRect.h" @@ -1362,17 +1361,17 @@ nsComputedDOMStyle::DoGetContent() case eStyleContentType_Attr: { // XXXbholley: We don't correctly serialize namespaces here. Doing so // would require either storing the prefix on the nsStyleContentAttr, // or poking at the namespaces in the stylesheet to map from the // namespace URL. nsAutoString str; nsStyleUtil::AppendEscapedCSSIdent( nsDependentString(data.GetAttr()->mName->GetUTF16String()), str); - val->SetString(str, CSSPrimitiveValueBinding::CSS_ATTR); + val->SetString(str, nsROCSSPrimitiveValue::CSS_ATTR); break; } case eStyleContentType_Counter: case eStyleContentType_Counters: { /* FIXME: counters should really use an object */ nsAutoString str; if (type == eStyleContentType_Counter) { str.AppendLiteral("counter("); @@ -1387,17 +1386,17 @@ nsComputedDOMStyle::DoGetContent() nsStyleUtil::AppendEscapedCSSString(counters->mSeparator, str); } if (counters->mCounterStyle != CounterStyleManager::GetDecimalStyle()) { str.AppendLiteral(", "); AppendCounterStyle(counters->mCounterStyle, str); } str.Append(char16_t(')')); - val->SetString(str, CSSPrimitiveValueBinding::CSS_COUNTER); + val->SetString(str, nsROCSSPrimitiveValue::CSS_COUNTER); break; } case eStyleContentType_OpenQuote: val->SetIdent(eCSSKeyword_open_quote); break; case eStyleContentType_CloseQuote: val->SetIdent(eCSSKeyword_close_quote); break;
--- a/layout/style/nsDOMCSSRGBColor.cpp +++ b/layout/style/nsDOMCSSRGBColor.cpp @@ -3,38 +3,23 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ /* DOM object representing color values in DOM computed style */ #include "nsDOMCSSRGBColor.h" -#include "mozilla/dom/RGBColorBinding.h" #include "nsROCSSPrimitiveValue.h" using namespace mozilla; nsDOMCSSRGBColor::nsDOMCSSRGBColor(nsROCSSPrimitiveValue* aRed, nsROCSSPrimitiveValue* aGreen, nsROCSSPrimitiveValue* aBlue, nsROCSSPrimitiveValue* aAlpha, bool aHasAlpha) : mRed(aRed), mGreen(aGreen), mBlue(aBlue), mAlpha(aAlpha) , mHasAlpha(aHasAlpha) { } -nsDOMCSSRGBColor::~nsDOMCSSRGBColor(void) -{ -} - -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMCSSRGBColor, mAlpha, mBlue, mGreen, mRed) - -NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsDOMCSSRGBColor, AddRef) -NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsDOMCSSRGBColor, Release) - -JSObject* -nsDOMCSSRGBColor::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) -{ - return dom::RGBColorBinding::Wrap(aCx, this, aGivenProto); -} - +nsDOMCSSRGBColor::~nsDOMCSSRGBColor() = default;
--- a/layout/style/nsDOMCSSRGBColor.h +++ b/layout/style/nsDOMCSSRGBColor.h @@ -5,33 +5,30 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* DOM object representing color values in DOM computed style */ #ifndef nsDOMCSSRGBColor_h__ #define nsDOMCSSRGBColor_h__ #include "mozilla/Attributes.h" -#include "nsWrapperCache.h" +#include "mozilla/RefPtr.h" class nsROCSSPrimitiveValue; -class nsDOMCSSRGBColor : public nsWrapperCache +class nsDOMCSSRGBColor final : public mozilla::RefCounted<nsDOMCSSRGBColor> { public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(nsDOMCSSRGBColor); nsDOMCSSRGBColor(nsROCSSPrimitiveValue* aRed, nsROCSSPrimitiveValue* aGreen, nsROCSSPrimitiveValue* aBlue, nsROCSSPrimitiveValue* aAlpha, bool aHasAlpha); - NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsDOMCSSRGBColor) - - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsDOMCSSRGBColor) - bool HasAlpha() const { return mHasAlpha; } // RGBColor webidl interface nsROCSSPrimitiveValue* Red() const { return mRed; } nsROCSSPrimitiveValue* Green() const @@ -42,26 +39,19 @@ public: { return mBlue; } nsROCSSPrimitiveValue* Alpha() const { return mAlpha; } - nsISupports* GetParentObject() const - { - return nullptr; - } + ~nsDOMCSSRGBColor(); - JSObject *WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) final; - -private: - virtual ~nsDOMCSSRGBColor(void); - +protected: RefPtr<nsROCSSPrimitiveValue> mRed; RefPtr<nsROCSSPrimitiveValue> mGreen; RefPtr<nsROCSSPrimitiveValue> mBlue; RefPtr<nsROCSSPrimitiveValue> mAlpha; bool mHasAlpha; }; #endif // nsDOMCSSRGBColor_h__
--- a/layout/style/nsDOMCSSRect.cpp +++ b/layout/style/nsDOMCSSRect.cpp @@ -3,40 +3,21 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ /* DOM object representing rectangle values in DOM computed style */ #include "nsDOMCSSRect.h" -#include "mozilla/dom/RectBinding.h" #include "nsROCSSPrimitiveValue.h" using namespace mozilla; nsDOMCSSRect::nsDOMCSSRect(nsROCSSPrimitiveValue* aTop, nsROCSSPrimitiveValue* aRight, nsROCSSPrimitiveValue* aBottom, nsROCSSPrimitiveValue* aLeft) : mTop(aTop), mRight(aRight), mBottom(aBottom), mLeft(aLeft) { } -nsDOMCSSRect::~nsDOMCSSRect(void) -{ -} - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCSSRect) - NS_INTERFACE_MAP_ENTRY(nsISupports) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY -NS_INTERFACE_MAP_END - -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCSSRect) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCSSRect) - -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMCSSRect, mTop, mBottom, mLeft, mRight) - -JSObject* -nsDOMCSSRect::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) -{ - return dom::RectBinding::Wrap(cx, this, aGivenProto); -} +nsDOMCSSRect::~nsDOMCSSRect() = default;
--- a/layout/style/nsDOMCSSRect.h +++ b/layout/style/nsDOMCSSRect.h @@ -5,44 +5,36 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* DOM object representing rectangle values in DOM computed style */ #ifndef nsDOMCSSRect_h_ #define nsDOMCSSRect_h_ #include "mozilla/Attributes.h" -#include "nsCycleCollectionParticipant.h" -#include "nsWrapperCache.h" +#include "mozilla/RefPtr.h" class nsROCSSPrimitiveValue; -class nsDOMCSSRect final : public nsISupports, - public nsWrapperCache +class nsDOMCSSRect final : public RefCounted<nsDOMCSSRect> { public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(nsDOMCSSRect); + nsDOMCSSRect(nsROCSSPrimitiveValue* aTop, nsROCSSPrimitiveValue* aRight, nsROCSSPrimitiveValue* aBottom, nsROCSSPrimitiveValue* aLeft); - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMCSSRect) - nsROCSSPrimitiveValue* Top() const { return mTop; } nsROCSSPrimitiveValue* Right() const { return mRight; } nsROCSSPrimitiveValue* Bottom() const { return mBottom; } nsROCSSPrimitiveValue* Left() const { return mLeft; } - nsISupports* GetParentObject() const { return nullptr; } - - JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) final; - -protected: - virtual ~nsDOMCSSRect(void); + ~nsDOMCSSRect(); private: RefPtr<nsROCSSPrimitiveValue> mTop; RefPtr<nsROCSSPrimitiveValue> mRight; RefPtr<nsROCSSPrimitiveValue> mBottom; RefPtr<nsROCSSPrimitiveValue> mLeft; };
--- a/layout/style/nsDOMCSSValueList.cpp +++ b/layout/style/nsDOMCSSValueList.cpp @@ -2,48 +2,29 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ /* DOM object representing lists of values in DOM computed style */ #include "nsDOMCSSValueList.h" -#include "mozilla/dom/CSSValueBinding.h" -#include "mozilla/dom/CSSValueListBinding.h" +#include "nsString.h" +#include "mozilla/ErrorResult.h" #include "mozilla/Move.h" using namespace mozilla; using namespace mozilla::dom; nsDOMCSSValueList::nsDOMCSSValueList(bool aCommaDelimited, bool aReadonly) : CSSValue(), mCommaDelimited(aCommaDelimited), mReadonly(aReadonly) { } -nsDOMCSSValueList::~nsDOMCSSValueList() -{ -} - -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCSSValueList) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCSSValueList) - -// QueryInterface implementation for nsDOMCSSValueList -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCSSValueList) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, CSSValue) -NS_INTERFACE_MAP_END - -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMCSSValueList, mCSSValues) - -JSObject* -nsDOMCSSValueList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) -{ - return dom::CSSValueListBinding::Wrap(cx, this, aGivenProto); -} +nsDOMCSSValueList::~nsDOMCSSValueList() = default; void nsDOMCSSValueList::AppendCSSValue(already_AddRefed<CSSValue> aValue) { RefPtr<CSSValue> val = aValue; mCSSValues.AppendElement(Move(val)); } @@ -104,10 +85,10 @@ nsDOMCSSValueList::SetCssText(const nsAS } MOZ_ASSERT_UNREACHABLE("Can't SetCssText yet: please write me!"); } uint16_t nsDOMCSSValueList::CssValueType() const { - return CSSValueBinding::CSS_VALUE_LIST; + return CSSValue::CSS_VALUE_LIST; }
--- a/layout/style/nsDOMCSSValueList.h +++ b/layout/style/nsDOMCSSValueList.h @@ -10,19 +10,16 @@ #define nsDOMCSSValueList_h___ #include "CSSValue.h" #include "nsTArray.h" class nsDOMCSSValueList final : public mozilla::dom::CSSValue { public: - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMCSSValueList) - // nsDOMCSSValueList nsDOMCSSValueList(bool aCommaDelimited, bool aReadonly); /** * Adds a value to this list. */ void AppendCSSValue(already_AddRefed<CSSValue> aValue); @@ -43,25 +40,18 @@ public: return mCSSValues.SafeElementAt(aIndex); } uint32_t Length() const { return mCSSValues.Length(); } - nsISupports* GetParentObject() - { - return nullptr; - } - - virtual JSObject *WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override; - -private: - ~nsDOMCSSValueList(); +protected: + virtual ~nsDOMCSSValueList(); bool mCommaDelimited; // some value lists use a comma // as the delimiter, some just use // spaces. bool mReadonly; // Are we read-only? InfallibleTArray<RefPtr<CSSValue> > mCSSValues;
--- a/layout/style/nsROCSSPrimitiveValue.cpp +++ b/layout/style/nsROCSSPrimitiveValue.cpp @@ -3,111 +3,66 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ /* DOM object representing values in DOM computed style */ #include "nsROCSSPrimitiveValue.h" -#include "mozilla/dom/CSSPrimitiveValueBinding.h" #include "nsPresContext.h" #include "nsStyleUtil.h" #include "nsDOMCSSRGBColor.h" #include "nsDOMCSSRect.h" #include "nsIURI.h" #include "nsError.h" -// There is no CSS_TURN constant on the CSSPrimitiveValue interface, -// since that unit is newer than DOM Level 2 Style, and CSS OM will -// probably expose CSS values in some other way in the future. We -// use this value in mType for "turn"-unit angles, but we define it -// here to avoid exposing it to content. -#define CSS_TURN 30U -// Likewise we have some internal aliases for CSS_NUMBER that we don't -// want to expose. -#define CSS_NUMBER_INT32 31U -#define CSS_NUMBER_UINT32 32U - using namespace mozilla; using namespace mozilla::dom; nsROCSSPrimitiveValue::nsROCSSPrimitiveValue() - : CSSValue(), mType(CSSPrimitiveValueBinding::CSS_PX) + : CSSValue(), mType(CSS_PX) { mValue.mAppUnits = 0; } nsROCSSPrimitiveValue::~nsROCSSPrimitiveValue() { Reset(); } -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsROCSSPrimitiveValue) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsROCSSPrimitiveValue) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsROCSSPrimitiveValue) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, CSSValue) -NS_INTERFACE_MAP_END - -NS_IMPL_CYCLE_COLLECTION_CLASS(nsROCSSPrimitiveValue) - -NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsROCSSPrimitiveValue) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsROCSSPrimitiveValue) - if (tmp->mType == CSSPrimitiveValueBinding::CSS_URI) { - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mValue.mURI) - } else if (tmp->mType == CSSPrimitiveValueBinding::CSS_RGBCOLOR) { - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mValue.mColor) - } else if (tmp->mType == CSSPrimitiveValueBinding::CSS_RECT) { - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mValue.mRect) - } -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsROCSSPrimitiveValue) - NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER - tmp->Reset(); -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -JSObject* -nsROCSSPrimitiveValue::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) -{ - return dom::CSSPrimitiveValueBinding::Wrap(cx, this, aGivenProto); -} - nsresult nsROCSSPrimitiveValue::GetCssText(nsAString& aCssText) { nsAutoString tmpStr; aCssText.Truncate(); nsresult result = NS_OK; switch (mType) { - case CSSPrimitiveValueBinding::CSS_PX: + case CSS_PX: { float val = nsPresContext::AppUnitsToFloatCSSPixels(mValue.mAppUnits); nsStyleUtil::AppendCSSNumber(val, tmpStr); tmpStr.AppendLiteral("px"); break; } - case CSSPrimitiveValueBinding::CSS_IDENT: + case CSS_IDENT: { AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue.mKeyword), tmpStr); break; } - case CSSPrimitiveValueBinding::CSS_STRING: - case CSSPrimitiveValueBinding::CSS_COUNTER: /* FIXME: COUNTER should use an object */ + case CSS_STRING: + case CSS_COUNTER: /* FIXME: COUNTER should use an object */ { tmpStr.Append(mValue.mString); break; } - case CSSPrimitiveValueBinding::CSS_URI: + case CSS_URI: { if (mValue.mURI) { nsAutoCString specUTF8; nsresult rv = mValue.mURI->GetSpec(specUTF8); NS_ENSURE_SUCCESS(rv, rv); tmpStr.AssignLiteral("url("); nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(specUTF8), @@ -117,69 +72,69 @@ nsROCSSPrimitiveValue::GetCssText(nsAStr // http://dev.w3.org/csswg/css3-values/#attr defines // 'about:invalid' as the default value for url attributes, // so let's also use it here as the default computed value // for invalid URLs. tmpStr.AssignLiteral(u"url(about:invalid)"); } break; } - case CSSPrimitiveValueBinding::CSS_ATTR: + case CSS_ATTR: { tmpStr.AppendLiteral("attr("); tmpStr.Append(mValue.mString); tmpStr.Append(char16_t(')')); break; } - case CSSPrimitiveValueBinding::CSS_PERCENTAGE: + case CSS_PERCENTAGE: { nsStyleUtil::AppendCSSNumber(mValue.mFloat * 100, tmpStr); tmpStr.Append(char16_t('%')); break; } - case CSSPrimitiveValueBinding::CSS_NUMBER: + case CSS_NUMBER: { nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr); break; } case CSS_NUMBER_INT32: { tmpStr.AppendInt(mValue.mInt32); break; } case CSS_NUMBER_UINT32: { tmpStr.AppendInt(mValue.mUint32); break; } - case CSSPrimitiveValueBinding::CSS_DEG: + case CSS_DEG: { nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr); tmpStr.AppendLiteral("deg"); break; } - case CSSPrimitiveValueBinding::CSS_GRAD: + case CSS_GRAD: { nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr); tmpStr.AppendLiteral("grad"); break; } - case CSSPrimitiveValueBinding::CSS_RAD: + case CSS_RAD: { nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr); tmpStr.AppendLiteral("rad"); break; } case CSS_TURN: { nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr); tmpStr.AppendLiteral("turn"); break; } - case CSSPrimitiveValueBinding::CSS_RECT: + case CSS_RECT: { NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null"); NS_NAMED_LITERAL_STRING(comma, ", "); nsAutoString sideValue; tmpStr.AssignLiteral("rect("); // get the top result = mValue.mRect->Top()->GetCssText(sideValue); if (NS_FAILED(result)) @@ -197,17 +152,17 @@ nsROCSSPrimitiveValue::GetCssText(nsAStr tmpStr.Append(sideValue + comma); // get the left result = mValue.mRect->Left()->GetCssText(sideValue); if (NS_FAILED(result)) break; tmpStr.Append(sideValue + NS_LITERAL_STRING(")")); break; } - case CSSPrimitiveValueBinding::CSS_RGBCOLOR: + case CSS_RGBCOLOR: { NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null"); ErrorResult error; NS_NAMED_LITERAL_STRING(comma, ", "); nsAutoString colorValue; if (mValue.mColor->HasAlpha()) tmpStr.AssignLiteral("rgba("); else @@ -238,34 +193,34 @@ nsROCSSPrimitiveValue::GetCssText(nsAStr break; tmpStr.Append(comma + colorValue); } tmpStr.Append(')'); break; } - case CSSPrimitiveValueBinding::CSS_S: + case CSS_S: { nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr); tmpStr.Append('s'); break; } - case CSSPrimitiveValueBinding::CSS_CM: - case CSSPrimitiveValueBinding::CSS_MM: - case CSSPrimitiveValueBinding::CSS_IN: - case CSSPrimitiveValueBinding::CSS_PT: - case CSSPrimitiveValueBinding::CSS_PC: - case CSSPrimitiveValueBinding::CSS_UNKNOWN: - case CSSPrimitiveValueBinding::CSS_EMS: - case CSSPrimitiveValueBinding::CSS_EXS: - case CSSPrimitiveValueBinding::CSS_MS: - case CSSPrimitiveValueBinding::CSS_HZ: - case CSSPrimitiveValueBinding::CSS_KHZ: - case CSSPrimitiveValueBinding::CSS_DIMENSION: + case CSS_CM: + case CSS_MM: + case CSS_IN: + case CSS_PT: + case CSS_PC: + case CSS_UNKNOWN: + case CSS_EMS: + case CSS_EXS: + case CSS_MS: + case CSS_HZ: + case CSS_KHZ: + case CSS_DIMENSION: NS_ERROR("We have a bogus value set. This should not happen"); return NS_ERROR_DOM_INVALID_ACCESS_ERR; } if (NS_SUCCEEDED(result)) { aCssText.Assign(tmpStr); } @@ -282,106 +237,106 @@ void nsROCSSPrimitiveValue::SetCssText(const nsAString& aText, ErrorResult& aRv) { aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); } uint16_t nsROCSSPrimitiveValue::CssValueType() const { - return CSSValueBinding::CSS_PRIMITIVE_VALUE; + return CSSValue::CSS_PRIMITIVE_VALUE; } void nsROCSSPrimitiveValue::SetFloatValue(uint16_t aType, float aVal, ErrorResult& aRv) { aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); } float nsROCSSPrimitiveValue::GetFloatValue(uint16_t aUnitType, ErrorResult& aRv) { switch(aUnitType) { - case CSSPrimitiveValueBinding::CSS_PX: - if (mType == CSSPrimitiveValueBinding::CSS_PX) { + case CSS_PX: + if (mType == CSS_PX) { return nsPresContext::AppUnitsToFloatCSSPixels(mValue.mAppUnits); } break; - case CSSPrimitiveValueBinding::CSS_CM: - if (mType == CSSPrimitiveValueBinding::CSS_PX) { + case CSS_CM: + if (mType == CSS_PX) { return mValue.mAppUnits * CM_PER_INCH_FLOAT / nsPresContext::AppUnitsPerCSSInch(); } break; - case CSSPrimitiveValueBinding::CSS_MM: - if (mType == CSSPrimitiveValueBinding::CSS_PX) { + case CSS_MM: + if (mType == CSS_PX) { return mValue.mAppUnits * MM_PER_INCH_FLOAT / nsPresContext::AppUnitsPerCSSInch(); } break; - case CSSPrimitiveValueBinding::CSS_IN: - if (mType == CSSPrimitiveValueBinding::CSS_PX) { + case CSS_IN: + if (mType == CSS_PX) { return mValue.mAppUnits / nsPresContext::AppUnitsPerCSSInch(); } break; - case CSSPrimitiveValueBinding::CSS_PT: - if (mType == CSSPrimitiveValueBinding::CSS_PX) { + case CSS_PT: + if (mType == CSS_PX) { return mValue.mAppUnits * POINTS_PER_INCH_FLOAT / nsPresContext::AppUnitsPerCSSInch(); } break; - case CSSPrimitiveValueBinding::CSS_PC: - if (mType == CSSPrimitiveValueBinding::CSS_PX) { + case CSS_PC: + if (mType == CSS_PX) { return mValue.mAppUnits * 6.0f / nsPresContext::AppUnitsPerCSSInch(); } break; - case CSSPrimitiveValueBinding::CSS_PERCENTAGE: - if (mType == CSSPrimitiveValueBinding::CSS_PERCENTAGE) { + case CSS_PERCENTAGE: + if (mType == CSS_PERCENTAGE) { return mValue.mFloat * 100; } break; - case CSSPrimitiveValueBinding::CSS_NUMBER: - if (mType == CSSPrimitiveValueBinding::CSS_NUMBER) { + case CSS_NUMBER: + if (mType == CSS_NUMBER) { return mValue.mFloat; } if (mType == CSS_NUMBER_INT32) { return mValue.mInt32; } if (mType == CSS_NUMBER_UINT32) { return mValue.mUint32; } break; - case CSSPrimitiveValueBinding::CSS_UNKNOWN: - case CSSPrimitiveValueBinding::CSS_EMS: - case CSSPrimitiveValueBinding::CSS_EXS: - case CSSPrimitiveValueBinding::CSS_DEG: - case CSSPrimitiveValueBinding::CSS_RAD: - case CSSPrimitiveValueBinding::CSS_GRAD: - case CSSPrimitiveValueBinding::CSS_MS: - case CSSPrimitiveValueBinding::CSS_S: - case CSSPrimitiveValueBinding::CSS_HZ: - case CSSPrimitiveValueBinding::CSS_KHZ: - case CSSPrimitiveValueBinding::CSS_DIMENSION: - case CSSPrimitiveValueBinding::CSS_STRING: - case CSSPrimitiveValueBinding::CSS_URI: - case CSSPrimitiveValueBinding::CSS_IDENT: - case CSSPrimitiveValueBinding::CSS_ATTR: - case CSSPrimitiveValueBinding::CSS_COUNTER: - case CSSPrimitiveValueBinding::CSS_RECT: - case CSSPrimitiveValueBinding::CSS_RGBCOLOR: + case CSS_UNKNOWN: + case CSS_EMS: + case CSS_EXS: + case CSS_DEG: + case CSS_RAD: + case CSS_GRAD: + case CSS_MS: + case CSS_S: + case CSS_HZ: + case CSS_KHZ: + case CSS_DIMENSION: + case CSS_STRING: + case CSS_URI: + case CSS_IDENT: + case CSS_ATTR: + case CSS_COUNTER: + case CSS_RECT: + case CSS_RGBCOLOR: break; } aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return 0; } void @@ -390,24 +345,24 @@ nsROCSSPrimitiveValue::SetStringValue(ui { aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); } void nsROCSSPrimitiveValue::GetStringValue(nsString& aReturn, ErrorResult& aRv) { switch (mType) { - case CSSPrimitiveValueBinding::CSS_IDENT: + case CSS_IDENT: CopyUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue.mKeyword), aReturn); break; - case CSSPrimitiveValueBinding::CSS_STRING: - case CSSPrimitiveValueBinding::CSS_ATTR: + case CSS_STRING: + case CSS_ATTR: aReturn.Assign(mValue.mString); break; - case CSSPrimitiveValueBinding::CSS_URI: { + case CSS_URI: { nsAutoCString spec; if (mValue.mURI) { nsresult rv = mValue.mURI->GetSpec(spec); if (NS_FAILED(rv)) { aRv.Throw(rv); return; } } @@ -425,43 +380,43 @@ void nsROCSSPrimitiveValue::GetCounterValue(ErrorResult& aRv) { aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); } nsDOMCSSRect* nsROCSSPrimitiveValue::GetRectValue(ErrorResult& aRv) { - if (mType != CSSPrimitiveValueBinding::CSS_RECT) { + if (mType != CSS_RECT) { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return nullptr; } NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null"); return mValue.mRect; } nsDOMCSSRGBColor* nsROCSSPrimitiveValue::GetRGBColorValue(ErrorResult& aRv) { - if (mType != CSSPrimitiveValueBinding::CSS_RGBCOLOR) { + if (mType != CSS_RGBCOLOR) { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return nullptr; } NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null"); return mValue.mColor; } void nsROCSSPrimitiveValue::SetNumber(float aValue) { Reset(); mValue.mFloat = aValue; - mType = CSSPrimitiveValueBinding::CSS_NUMBER; + mType = CSS_NUMBER; } void nsROCSSPrimitiveValue::SetNumber(int32_t aValue) { Reset(); mValue.mInt32 = aValue; mType = CSS_NUMBER_INT32; @@ -475,188 +430,187 @@ nsROCSSPrimitiveValue::SetNumber(uint32_ mType = CSS_NUMBER_UINT32; } void nsROCSSPrimitiveValue::SetPercent(float aValue) { Reset(); mValue.mFloat = aValue; - mType = CSSPrimitiveValueBinding::CSS_PERCENTAGE; + mType = CSS_PERCENTAGE; } void nsROCSSPrimitiveValue::SetDegree(float aValue) { Reset(); mValue.mFloat = aValue; - mType = CSSPrimitiveValueBinding::CSS_DEG; + mType = CSS_DEG; } void nsROCSSPrimitiveValue::SetGrad(float aValue) { Reset(); mValue.mFloat = aValue; - mType = CSSPrimitiveValueBinding::CSS_GRAD; + mType = CSS_GRAD; } void nsROCSSPrimitiveValue::SetRadian(float aValue) { Reset(); mValue.mFloat = aValue; - mType = CSSPrimitiveValueBinding::CSS_RAD; + mType = CSS_RAD; } void nsROCSSPrimitiveValue::SetTurn(float aValue) { Reset(); mValue.mFloat = aValue; mType = CSS_TURN; } void nsROCSSPrimitiveValue::SetAppUnits(nscoord aValue) { Reset(); mValue.mAppUnits = aValue; - mType = CSSPrimitiveValueBinding::CSS_PX; + mType = CSS_PX; } void nsROCSSPrimitiveValue::SetAppUnits(float aValue) { SetAppUnits(NSToCoordRound(aValue)); } void nsROCSSPrimitiveValue::SetIdent(nsCSSKeyword aKeyword) { MOZ_ASSERT(aKeyword != eCSSKeyword_UNKNOWN && 0 <= aKeyword && aKeyword < eCSSKeyword_COUNT, "bad keyword"); Reset(); mValue.mKeyword = aKeyword; - mType = CSSPrimitiveValueBinding::CSS_IDENT; + mType = CSS_IDENT; } // FIXME: CSS_STRING should imply a string with "" and a need for escaping. void nsROCSSPrimitiveValue::SetString(const nsACString& aString, uint16_t aType) { Reset(); mValue.mString = ToNewUnicode(aString); if (mValue.mString) { mType = aType; } else { // XXXcaa We should probably let the caller know we are out of memory - mType = CSSPrimitiveValueBinding::CSS_UNKNOWN; + mType = CSS_UNKNOWN; } } // FIXME: CSS_STRING should imply a string with "" and a need for escaping. void nsROCSSPrimitiveValue::SetString(const nsAString& aString, uint16_t aType) { Reset(); mValue.mString = ToNewUnicode(aString); if (mValue.mString) { mType = aType; } else { // XXXcaa We should probably let the caller know we are out of memory - mType = CSSPrimitiveValueBinding::CSS_UNKNOWN; + mType = CSS_UNKNOWN; } } void nsROCSSPrimitiveValue::SetURI(nsIURI *aURI) { Reset(); mValue.mURI = aURI; NS_IF_ADDREF(mValue.mURI); - mType = CSSPrimitiveValueBinding::CSS_URI; + mType = CSS_URI; } void nsROCSSPrimitiveValue::SetColor(nsDOMCSSRGBColor* aColor) { MOZ_ASSERT(aColor, "Null RGBColor being set!"); Reset(); mValue.mColor = aColor; if (mValue.mColor) { NS_ADDREF(mValue.mColor); - mType = CSSPrimitiveValueBinding::CSS_RGBCOLOR; + mType = CSS_RGBCOLOR; } else { - mType = CSSPrimitiveValueBinding::CSS_UNKNOWN; + mType = CSS_UNKNOWN; } } void nsROCSSPrimitiveValue::SetRect(nsDOMCSSRect* aRect) { MOZ_ASSERT(aRect, "Null rect being set!"); Reset(); mValue.mRect = aRect; if (mValue.mRect) { NS_ADDREF(mValue.mRect); - mType = CSSPrimitiveValueBinding::CSS_RECT; + mType = CSS_RECT; } else { - mType = CSSPrimitiveValueBinding::CSS_UNKNOWN; + mType = CSS_UNKNOWN; } } void nsROCSSPrimitiveValue::SetTime(float aValue) { Reset(); mValue.mFloat = aValue; - mType = CSSPrimitiveValueBinding::CSS_S; + mType = CSS_S; } void nsROCSSPrimitiveValue::Reset() { switch (mType) { - case CSSPrimitiveValueBinding::CSS_IDENT: + case CSS_IDENT: break; - case CSSPrimitiveValueBinding::CSS_STRING: - case CSSPrimitiveValueBinding::CSS_ATTR: - case CSSPrimitiveValueBinding::CSS_COUNTER: // FIXME: Counter should use an object + case CSS_STRING: + case CSS_ATTR: + case CSS_COUNTER: // FIXME: Counter should use an object NS_ASSERTION(mValue.mString, "Null string should never happen"); free(mValue.mString); mValue.mString = nullptr; break; - case CSSPrimitiveValueBinding::CSS_URI: + case CSS_URI: NS_IF_RELEASE(mValue.mURI); break; - case CSSPrimitiveValueBinding::CSS_RECT: + case CSS_RECT: NS_ASSERTION(mValue.mRect, "Null Rect should never happen"); NS_RELEASE(mValue.mRect); break; - case CSSPrimitiveValueBinding::CSS_RGBCOLOR: + case CSS_RGBCOLOR: NS_ASSERTION(mValue.mColor, "Null RGBColor should never happen"); NS_RELEASE(mValue.mColor); break; } - mType = CSSPrimitiveValueBinding::CSS_UNKNOWN; + mType = CSS_UNKNOWN; } uint16_t nsROCSSPrimitiveValue::PrimitiveType() { // New value types were introduced but not added to CSS OM. // Return CSS_UNKNOWN to avoid exposing CSS_TURN to content. - if (mType > CSSPrimitiveValueBinding::CSS_RGBCOLOR) { - if (mType == CSS_NUMBER_INT32 || - mType == CSS_NUMBER_UINT32) { - return CSSPrimitiveValueBinding::CSS_NUMBER; + if (mType > CSS_RGBCOLOR) { + if (mType == CSS_NUMBER_INT32 || mType == CSS_NUMBER_UINT32) { + return CSS_NUMBER; } - return CSSPrimitiveValueBinding::CSS_UNKNOWN; + return CSS_UNKNOWN; } return mType; }
--- a/layout/style/nsROCSSPrimitiveValue.h +++ b/layout/style/nsROCSSPrimitiveValue.h @@ -4,37 +4,63 @@ * 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/. */ /* DOM object representing values in DOM computed style */ #ifndef nsROCSSPrimitiveValue_h___ #define nsROCSSPrimitiveValue_h___ -#include "mozilla/dom/CSSPrimitiveValueBinding.h" -#include "mozilla/dom/CSSValueBinding.h" - #include "nsCSSKeywords.h" #include "CSSValue.h" #include "nsCOMPtr.h" #include "nsCoord.h" class nsIURI; class nsDOMCSSRect; class nsDOMCSSRGBColor; /** * Read-only CSS primitive value - a DOM object representing values in DOM * computed style. */ class nsROCSSPrimitiveValue final : public mozilla::dom::CSSValue { public: - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsROCSSPrimitiveValue) + enum : uint16_t { + CSS_UNKNOWN, + CSS_NUMBER, + CSS_PERCENTAGE, + CSS_EMS, + CSS_EXS, + CSS_PX, + CSS_CM, + CSS_MM, + CSS_IN, + CSS_PT, + CSS_PC, + CSS_DEG, + CSS_RAD, + CSS_GRAD, + CSS_MS, + CSS_S, + CSS_HZ, + CSS_KHZ, + CSS_DIMENSION, + CSS_STRING, + CSS_URI, + CSS_IDENT, + CSS_ATTR, + CSS_COUNTER, + CSS_RECT, + CSS_RGBCOLOR, + CSS_TURN, + CSS_NUMBER_INT32, + CSS_NUMBER_UINT32, + }; // CSSValue void GetCssText(nsString& aText, mozilla::ErrorResult& aRv) final; void SetCssText(const nsAString& aText, mozilla::ErrorResult& aRv) final; uint16_t CssValueType() const final; // CSSPrimitiveValue uint16_t PrimitiveType(); @@ -59,38 +85,27 @@ public: void SetDegree(float aValue); void SetGrad(float aValue); void SetRadian(float aValue); void SetTurn(float aValue); void SetAppUnits(nscoord aValue); void SetAppUnits(float aValue); void SetIdent(nsCSSKeyword aKeyword); // FIXME: CSS_STRING should imply a string with "" and a need for escaping. - void SetString( - const nsACString& aString, - uint16_t aType = mozilla::dom::CSSPrimitiveValueBinding::CSS_STRING); + void SetString(const nsACString& aString, uint16_t aType = CSS_STRING); // FIXME: CSS_STRING should imply a string with "" and a need for escaping. - void SetString( - const nsAString& aString, - uint16_t aType = mozilla::dom::CSSPrimitiveValueBinding::CSS_STRING); + void SetString(const nsAString& aString, uint16_t aType = CSS_STRING); void SetURI(nsIURI *aURI); void SetColor(nsDOMCSSRGBColor* aColor); void SetRect(nsDOMCSSRect* aRect); void SetTime(float aValue); void Reset(); - nsISupports* GetParentObject() const - { - return nullptr; - } - - virtual JSObject *WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override; - -private: - ~nsROCSSPrimitiveValue(); + virtual ~nsROCSSPrimitiveValue(); +protected: uint16_t mType; union { nscoord mAppUnits; float mFloat; int32_t mInt32; uint32_t mUint32; @@ -101,13 +116,13 @@ private: nsIURI* MOZ_OWNING_REF mURI; nsCSSKeyword mKeyword; } mValue; }; inline nsROCSSPrimitiveValue* mozilla::dom::CSSValue::AsPrimitiveValue() { - return CssValueType() == CSSValueBinding::CSS_PRIMITIVE_VALUE ? - static_cast<nsROCSSPrimitiveValue*>(this) : nullptr; + return CssValueType() == mozilla::dom::CSSValue::CSS_PRIMITIVE_VALUE + ? static_cast<nsROCSSPrimitiveValue*>(this) : nullptr; } #endif /* nsROCSSPrimitiveValue_h___ */
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/RuntimeTelemetry.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/RuntimeTelemetry.java @@ -1,121 +1,55 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * vim: ts=4 sw=4 expandtab: * This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ package org.mozilla.geckoview; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.support.annotation.IntDef; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.util.Log; import org.mozilla.gecko.EventDispatcher; import org.mozilla.gecko.util.GeckoBundle; import org.mozilla.gecko.util.EventCallback; /** * The telemetry API gives access to telemetry data of the Gecko runtime. */ public final class RuntimeTelemetry { private final static String LOGTAG = "GeckoViewTelemetry"; private final static boolean DEBUG = false; private final GeckoRuntime mRuntime; private final EventDispatcher mEventDispatcher; - @Retention(RetentionPolicy.SOURCE) - @IntDef({ DATASET_BASE, DATASET_EXTENDED }) - public @interface DatasetType {} - - // Match with nsITelemetry. - /** - * The base dataset suitable for release builds. - */ - public static final int DATASET_BASE = 0; - /** - * The extended dataset suitable for pre-release builds. - */ - public static final int DATASET_EXTENDED = 1; - - @IntDef(flag = true, - value = { SNAPSHOT_HISTOGRAMS, SNAPSHOT_KEYED_HISTOGRAMS, - SNAPSHOT_SCALARS, SNAPSHOT_KEYED_SCALARS, - SNAPSHOT_ALL }) - public @interface SnapshotType {} - - // Match with GeckoViewTelemetryController. - /** - * Adds a "histogram" object entry to the snapshot response. - */ - public static final int SNAPSHOT_HISTOGRAMS = 1 << 0; - /** - * Adds a "keyedHistogram" object entry to the snapshot response. - */ - public static final int SNAPSHOT_KEYED_HISTOGRAMS = 1 << 1; - /** - * Adds a "scalars" object entry to the snapshot response. - */ - public static final int SNAPSHOT_SCALARS = 1 << 2; - /** - * Adds a "keyedScalars" object entry to the snapshot response. - */ - public static final int SNAPSHOT_KEYED_SCALARS = 1 << 3; - /** - * Adds all snapshot types to the response. - */ - public static final int SNAPSHOT_ALL = (1 << 4) - 1; - /* package */ RuntimeTelemetry(final @NonNull GeckoRuntime runtime) { mRuntime = runtime; mEventDispatcher = EventDispatcher.getInstance(); } /** * Retrieve all telemetry snapshots. + * The response bundle will contain following snapshots: + * <ul> + * <li>histograms</li> + * <li>keyedHistograms</li> + * <li>scalars</li> + * <li>keyedScalars</li> + * </ul> * - * @param dataset The dataset type to retreive. - * One of {@link #DATASET_BASE DATASET_*} flags. * @param clear Whether the retrieved snapshots should be cleared. * @param response Used to return the async response. */ public void getSnapshots( - final @DatasetType int dataset, final boolean clear, final @NonNull GeckoResponse<GeckoBundle> response) { - getSnapshots(SNAPSHOT_ALL, dataset, clear, response); - } - - /** - * Retrieve the requested telemetry snapshots. - * - * @param types The requested snapshot types. - * One or more of {@link #SNAPSHOT_HISTOGRAMS SNAPSHOT_*} flags. - * @param dataset The dataset type to retreive. - * One of {@link #DATASET_BASE DATASET_*} flags. - * @param clear Whether the retrieved snapshots should be cleared. - * @param response Used to return the async response. - */ - public void getSnapshots( - final @SnapshotType int types, - final @DatasetType int dataset, - final boolean clear, - final @NonNull GeckoResponse<GeckoBundle> response) { - final GeckoBundle msg = new GeckoBundle(3); - msg.putInt("types", types); - msg.putInt("dataset", dataset); + final GeckoBundle msg = new GeckoBundle(1); msg.putBoolean("clear", clear); mEventDispatcher.dispatch("GeckoView:TelemetrySnapshots", msg, new EventCallback() { @Override public void sendSuccess(final Object result) { response.respond((GeckoBundle) result); }
--- a/old-configure.in +++ b/old-configure.in @@ -1741,17 +1741,17 @@ dnl = If NSS was not detected in the sys dnl = use the one in the source tree (mozilla/security/nss) dnl ======================================================== MOZ_ARG_WITH_BOOL(system-nss, [ --with-system-nss Use system installed NSS], _USE_SYSTEM_NSS=1 ) if test -n "$_USE_SYSTEM_NSS"; then - AM_PATH_NSS(3.37, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) + AM_PATH_NSS(3.38, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) fi if test -z "$MOZ_SYSTEM_NSS"; then NSS_CFLAGS="-I${DIST}/include/nss" case "${OS_ARCH}" in # Only few platforms have been tested with GYP WINNT|Darwin|Linux|DragonFly|FreeBSD|NetBSD|OpenBSD|SunOS) ;;
--- a/python/mozbuild/mozbuild/action/xpidl-process.py +++ b/python/mozbuild/mozbuild/action/xpidl-process.py @@ -22,38 +22,39 @@ from xpidl.rust import print_rust_bindin from xpidl.rust_macros import print_rust_macros_bindings from xpidl.xpidl import IDLParser from mozbuild.makeutil import Makefile from mozbuild.pythonutil import iter_modules_in_path from mozbuild.util import FileAvoidWrite -def process(input_dir, inc_paths, bindings_conf, cache_dir, header_dir, - xpcrs_dir, xpt_dir, deps_dir, module, stems): +def process(input_dirs, inc_paths, bindings_conf, cache_dir, header_dir, + xpcrs_dir, xpt_dir, deps_dir, module, idl_files): p = IDLParser(outputdir=cache_dir) xpts = [] mk = Makefile() rule = mk.create_rule() glbl = {} execfile(bindings_conf, glbl) webidlconfig = glbl['DOMInterfaces'] # Write out dependencies for Python modules we import. If this list isn't # up to date, we will not re-process XPIDL files if the processor changes. rule.add_dependencies(iter_modules_in_path(topsrcdir)) - for stem in stems: - path = os.path.join(input_dir, '%s.idl' % stem) + for path in idl_files: + basename = os.path.basename(path) + stem, _ = os.path.splitext(basename) idl_data = open(path).read() idl = p.parse(idl_data, filename=path) - idl.resolve([input_dir] + inc_paths, p, webidlconfig) + idl.resolve(inc_paths, p, webidlconfig) header_path = os.path.join(header_dir, '%s.h' % stem) rs_rt_path = os.path.join(xpcrs_dir, 'rt', '%s.rs' % stem) rs_bt_path = os.path.join(xpcrs_dir, 'bt', '%s.rs' % stem) xpts.append(jsonxpt.build_typelib(idl)) rule.add_dependencies(idl.deps) @@ -86,30 +87,32 @@ def process(input_dir, inc_paths, bindin def main(argv): parser = argparse.ArgumentParser() parser.add_argument('--cache-dir', help='Directory in which to find or write cached lexer data.') parser.add_argument('--depsdir', help='Directory in which to write dependency files.') parser.add_argument('--bindings-conf', help='Path to the WebIDL binding configuration file.') - parser.add_argument('inputdir', - help='Directory in which to find source .idl files.') + parser.add_argument('--input-dir', dest='input_dirs', + action='append', default=[], + help='Directory(ies) in which to find source .idl files.') parser.add_argument('headerdir', help='Directory in which to write header files.') parser.add_argument('xpcrsdir', help='Directory in which to write rust xpcom binding files.') parser.add_argument('xptdir', help='Directory in which to write xpt file.') parser.add_argument('module', help='Final module name to use for linked output xpt file.') parser.add_argument('idls', nargs='+', - help='Source .idl file(s). Specified as stems only.') + help='Source .idl file(s).') parser.add_argument('-I', dest='incpath', action='append', default=[], help='Extra directories where to look for included .idl files.') args = parser.parse_args(argv) - process(args.inputdir, args.incpath, args.bindings_conf, args.cache_dir, + incpath = [os.path.join(topsrcdir, p) for p in args.incpath] + process(args.input_dirs, incpath, args.bindings_conf, args.cache_dir, args.headerdir, args.xpcrsdir, args.xptdir, args.depsdir, args.module, args.idls) if __name__ == '__main__': main(sys.argv[1:])
--- a/python/mozbuild/mozbuild/backend/common.py +++ b/python/mozbuild/mozbuild/backend/common.py @@ -54,38 +54,45 @@ class XPIDLManager(object): def __init__(self, config): self.config = config self.topsrcdir = config.topsrcdir self.topobjdir = config.topobjdir self.idls = {} self.modules = {} - def register_idl(self, idl, allow_existing=False): + def register_idl(self, idl): """Registers an IDL file with this instance. The IDL file will be built, installed, etc. """ basename = mozpath.basename(idl.source_path) + dirname = mozpath.dirname(idl.source_path) root = mozpath.splitext(basename)[0] xpt = '%s.xpt' % idl.module entry = { 'source': idl.source_path, 'module': idl.module, 'basename': basename, 'root': root, } - if not allow_existing and entry['basename'] in self.idls: + if entry['basename'] in self.idls: raise Exception('IDL already registered: %s' % entry['basename']) self.idls[entry['basename']] = entry - t = self.modules.setdefault(entry['module'], (idl.install_target, set())) - t[1].add(entry['root']) + # First element is a set of interface file basenames (no extension). + # + # Second element is a set of directory names where module IDLs + # can be found. Yes, we have XPIDL modules with files from + # multiple directories. + t = self.modules.setdefault(entry['module'], (set(), set())) + t[0].add(entry['source']) + t[1].add(dirname) class BinariesCollection(object): """Tracks state of binaries produced by the build.""" def __init__(self): self.shared_libraries = [] self.programs = []
--- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -1040,48 +1040,50 @@ class RecursiveMakeBackend(CommonBackend def _handle_idl_manager(self, manager): build_files = self._install_manifests['xpidl'] for p in ('Makefile', 'backend.mk', '.deps/.mkdir.done'): build_files.add_optional_exists(p) for idl in manager.idls.values(): - self._install_manifests['dist_idl'].add_link(idl['source'], - idl['basename']) self._install_manifests['dist_include'].add_optional_exists('%s.h' % idl['root']) for module in manager.modules: build_files.add_optional_exists(mozpath.join('.deps', '%s.pp' % module)) modules = manager.modules xpt_modules = sorted(modules.keys()) mk = Makefile() + all_directories = set() for module in xpt_modules: - install_target, sources = modules[module] + sources, directories = modules[module] + all_directories |= directories deps = sorted(sources) # It may seem strange to have the .idl files listed as # prerequisites both here and in the auto-generated .pp files. # It is necessary to list them here to handle the case where a # new .idl is added to an xpt. If we add a new .idl and nothing # else has changed, the new .idl won't be referenced anywhere # except in the command invocation. Therefore, the .xpt won't # be rebuilt because the dependencies say it is up to date. By # listing the .idls here, we ensure the make file has a # reference to the new .idl. Since the new .idl presumably has # an mtime newer than the .xpt, it will trigger xpt generation. mk.add_statement('%s_deps = %s' % (module, ' '.join(deps))) build_files.add_optional_exists('%s.xpt' % module) + mk.add_statement('all_idl_dirs = %s' % ' '.join(sorted(all_directories))) + rules = StringIO() mk.dump(rules, removal_guard=False) # Create dependency for output header so we force regeneration if the # header was deleted. This ideally should not be necessary. However, # some processes (such as PGO at the time this was implemented) wipe # out dist/include without regard to our install manifests.
--- a/python/mozbuild/mozbuild/backend/tup.py +++ b/python/mozbuild/mozbuild/backend/tup.py @@ -791,40 +791,48 @@ class TupBackend(CommonBackend): dist_idl_backend_file = self._get_backend_file('dist/idl') for idl in manager.idls.values(): dist_idl_backend_file.symlink_rule(idl['source'], output_group=self._installed_idls) backend_file = self._get_backend_file('xpcom/xpidl') backend_file.export_shell() + all_idl_directories = set() + all_idl_directories.update(*map(lambda x: x[1], manager.modules.itervalues())) + all_xpts = [] - for module, data in sorted(manager.modules.iteritems()): - _, idls = data + for module, (idls, _) in sorted(manager.modules.iteritems()): cmd = [ '$(PYTHON_PATH)', '$(PLY_INCLUDE)', '-I$(IDL_PARSER_DIR)', '-I$(IDL_PARSER_CACHE_DIR)', '$(topsrcdir)/python/mozbuild/mozbuild/action/xpidl-process.py', '--cache-dir', '$(IDL_PARSER_CACHE_DIR)', '--bindings-conf', '$(topsrcdir)/dom/bindings/Bindings.conf', - '$(DIST)/idl', + ] + + for d in all_idl_directories: + cmd.extend(['-I', d]) + + cmd.extend([ '$(DIST)/include', '$(DIST)/xpcrs', '.', module, - ] + ]) cmd.extend(sorted(idls)) all_xpts.append('$(MOZ_OBJ_ROOT)/%s/%s.xpt' % (backend_file.relobjdir, module)) outputs = ['%s.xpt' % module] - outputs.extend(['$(MOZ_OBJ_ROOT)/dist/include/%s.h' % f for f in sorted(idls)]) - outputs.extend(['$(MOZ_OBJ_ROOT)/dist/xpcrs/rt/%s.rs' % f for f in sorted(idls)]) - outputs.extend(['$(MOZ_OBJ_ROOT)/dist/xpcrs/bt/%s.rs' % f for f in sorted(idls)]) + stems = sorted(mozpath.splitext(mozpath.basename(idl))[0] for idl in idls) + outputs.extend(['$(MOZ_OBJ_ROOT)/dist/include/%s.h' % f for f in stems]) + outputs.extend(['$(MOZ_OBJ_ROOT)/dist/xpcrs/rt/%s.rs' % f for f in stems]) + outputs.extend(['$(MOZ_OBJ_ROOT)/dist/xpcrs/bt/%s.rs' % f for f in stems]) backend_file.rule( inputs=[ '$(MOZ_OBJ_ROOT)/xpcom/idl-parser/xpidl/xpidllex.py', '$(MOZ_OBJ_ROOT)/xpcom/idl-parser/xpidl/xpidlyacc.py', self._installed_idls, ], display='XPIDL %s' % module, cmd=cmd,
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py +++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py @@ -683,24 +683,18 @@ class TestRecursiveMakeBackend(BackendTe def test_xpidl_generation(self): """Ensure xpidl files and directories are written out.""" env = self._consume('xpidl', RecursiveMakeBackend) # Install manifests should contain entries. install_dir = mozpath.join(env.topobjdir, '_build_manifests', 'install') - self.assertTrue(os.path.isfile(mozpath.join(install_dir, 'dist_idl'))) self.assertTrue(os.path.isfile(mozpath.join(install_dir, 'xpidl'))) - m = InstallManifest(path=mozpath.join(install_dir, 'dist_idl')) - self.assertEqual(len(m), 2) - self.assertIn('bar.idl', m) - self.assertIn('foo.idl', m) - m = InstallManifest(path=mozpath.join(install_dir, 'xpidl')) self.assertIn('.deps/my_module.pp', m) m = InstallManifest(path=mozpath.join(install_dir, 'xpidl')) self.assertIn('my_module.xpt', m) m = InstallManifest(path=mozpath.join(install_dir, 'dist_include')) self.assertIn('foo.h', m)
--- a/taskcluster/docker/diffoscope/Dockerfile +++ b/taskcluster/docker/diffoscope/Dockerfile @@ -23,17 +23,17 @@ CMD ["/bin/bash", "--login"] RUN for s in debian_stretch debian_stretch-updates debian-security_stretch/updates; do \ echo "deb [check-valid-until=no] http://snapshot.debian.org/archive/${s%_*}/20171222T153610Z/ ${s#*_} main"; \ done > /etc/apt/sources.list RUN apt-get update -q && \ apt-get install -yyq diffoscope libc++abi1 locales python3-setuptools python2.7 python-pip git && \ sed -i '/en_US.UTF-8/s/^# *//' /etc/locale.gen && \ locale-gen && \ - git clone https://anonscm.debian.org/git/reproducible/diffoscope.git /tmp/diffoscope && \ + git clone https://salsa.debian.org/reproducible-builds/diffoscope.git /tmp/diffoscope && \ git -C /tmp/diffoscope checkout 202caf9d5d134e95f870d5f19f89511d635c27e4 && \ (cd /tmp/diffoscope && python3 setup.py install ) && \ rm -rf /tmp/diffoscope && \ apt-get clean # %include taskcluster/scripts/run-task COPY topsrcdir/taskcluster/scripts/run-task /builds/worker/bin/run-task
--- a/taskcluster/docker/recipes/ubuntu1604-test-system-setup.sh +++ b/taskcluster/docker/recipes/ubuntu1604-test-system-setup.sh @@ -51,16 +51,17 @@ apt_packages+=('libxxf86vm1') apt_packages+=('llvm') apt_packages+=('llvm-dev') apt_packages+=('llvm-runtime') apt_packages+=('nano') apt_packages+=('net-tools') apt_packages+=('pulseaudio') apt_packages+=('pulseaudio-module-bluetooth') apt_packages+=('pulseaudio-module-gconf') +apt_packages+=('qemu-kvm') apt_packages+=('rlwrap') apt_packages+=('screen') apt_packages+=('software-properties-common') apt_packages+=('sudo') apt_packages+=('tar') apt_packages+=('ttf-dejavu') apt_packages+=('ubuntu-desktop') apt_packages+=('unzip')
--- a/taskcluster/scripts/run-task +++ b/taskcluster/scripts/run-task @@ -492,16 +492,21 @@ def main(args): uid = user.pw_uid gid = group.gr_gid else: print('error: run-task must be run as root on POSIX platforms') return 1 else: uid = gid = gids = None + if os.path.exists("/dev/kvm"): + # Ensure kvm permissions for worker, required for Android x86 + st = os.stat("/dev/kvm") + os.chmod("/dev/kvm", st.st_mode | 0666) + # Validate caches. # # Taskgraph should pass in a list of paths that are caches via an # environment variable (which we don't want to pass down to child # processes). if 'TASKCLUSTER_CACHES' in os.environ: caches = os.environ['TASKCLUSTER_CACHES'].split(';')
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-025.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-025.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-026.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-026.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-028.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-028.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-029.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-029.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-031.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-031.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-032.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-032.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-033.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-033.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-034.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-034.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-035.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-035.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-036.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-036.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-372.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-372.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-373.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-373.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-375.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-375.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-376.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-376.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-378.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-378.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-379.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-379.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-380.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-380.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-381.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-381.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-382.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-382.xht] - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-383.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[first-letter-punctuation-383.xht] - expected: FAIL
--- a/toolkit/components/telemetry/geckoview/GeckoViewTelemetryController.jsm +++ b/toolkit/components/telemetry/geckoview/GeckoViewTelemetryController.jsm @@ -14,62 +14,46 @@ XPCOMUtils.defineLazyModuleGetters(this, }); GeckoViewUtils.initLogging("GeckoView.TelemetryController", this); var EXPORTED_SYMBOLS = ["GeckoViewTelemetryController"]; /* global debug warn */ -/** - * Telemetry snapshot API adaptors used to retrieve one or more snapshots - * for GeckoView:TelemetrySnapshots requests. - * Match with RuntimeTelemetry.SNAPSHOT_* and nsITelemetry.idl. - */ -const TelemetrySnapshots = [ - { - type: "histograms", - flag: (1 << 0), - get: (dataset, clear) => Services.telemetry.snapshotHistograms( - dataset, false, clear) - }, - { - type: "keyedHistograms", - flag: (1 << 1), - get: (dataset, clear) => Services.telemetry.snapshotKeyedHistograms( - dataset, false, clear) - }, - { - type: "scalars", - flag: (1 << 2), - get: (dataset, clear) => Services.telemetry.snapshotScalars( - dataset, clear) - }, - { - type: "keyedScalars", - flag: (1 << 3), - get: (dataset, clear) => Services.telemetry.snapshotKeyedScalars( - dataset, clear) - }, -]; +// Persistent data loading topic - see TelemetryGeckoViewPersistence.cpp. +const LOAD_COMPLETE_TOPIC = "internal-telemetry-geckoview-load-complete"; const GeckoViewTelemetryController = { /** * Setup the Telemetry recording flags. This must be called * in all the processes that need to collect Telemetry. */ setup() { - debug `setup`; - TelemetryUtils.setTelemetryRecordingFlags(); - debug `setup - canRecordPrereleaseData ${Services.telemetry.canRecordPrereleaseData - }, canRecordReleaseData ${Services.telemetry.canRecordReleaseData}`; + debug `setup - + canRecordPrereleaseData ${Services.telemetry.canRecordPrereleaseData}, + canRecordReleaseData ${Services.telemetry.canRecordReleaseData}`; if (GeckoViewUtils.IS_PARENT_PROCESS) { + // Prevent dispatching snapshots before persistent data has been loaded. + this._loadComplete = new Promise(resolve => { + Services.obs.addObserver(function observer(aSubject, aTopic, aData) { + if (aTopic !== LOAD_COMPLETE_TOPIC) { + warn `Received unexpected topic ${aTopic}`; + return; + } + debug `observed ${aTopic} - ready to handle telemetry requests`; + // Loading data has completed, discard this observer. + Services.obs.removeObserver(observer, LOAD_COMPLETE_TOPIC); + resolve(); + }, LOAD_COMPLETE_TOPIC); + }); + try { EventDispatcher.instance.registerListener(this, [ "GeckoView:TelemetrySnapshots", ]); } catch (e) { warn `Failed registering GeckoView:TelemetrySnapshots listener: ${e}`; } } @@ -86,28 +70,50 @@ const GeckoViewTelemetryController = { onEvent(aEvent, aData, aCallback) { debug `onEvent: aEvent=${aEvent}, aData=${aData}`; if (aEvent !== "GeckoView:TelemetrySnapshots") { warn `Received unexpected event ${aEvent}`; return; } - const { clear, types, dataset } = aData; - let snapshots = {}; + // Handle this request when loading has completed. + this._loadComplete.then(() => this.retrieveSnapshots(aData.clear, aCallback)); + }, + + /** + * Retrieve snapshots and forward them to the callback. + * + * @param aClear True if snapshot data should be cleared after retrieving. + * @param aCallback Callback implementing nsIAndroidEventCallback. + */ + retrieveSnapshots(aClear, aCallback) { + debug `retrieveSnapshots`; + + // Selecting the opt-in dataset will ensure that we retrieve opt-in probes + // (iff canRecordPreRelease == true) and opt-out probes + // (iff canRecordRelease == true) if they are being recorded. + const dataset = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN; - // Iterate over all snapshot types, retreive and assemble results. - for (const tel of TelemetrySnapshots) { - if ((tel.flag & types) == 0) { - // This snapshot type has not been requested. - continue; - } - const snapshot = tel.get(dataset, clear); - if (!snapshot) { - aCallback.onError(`Failed retrieving ${tel.type} snapshot!`); - return; - } - snapshots[tel.type] = snapshot; + const snapshots = { + histograms: Services.telemetry.snapshotHistograms( + dataset, /* subsession */ false, /* clear */ false), + keyedHistograms: Services.telemetry.snapshotKeyedHistograms( + dataset, /* subsession */ false, /* clear */ false), + scalars: Services.telemetry.snapshotScalars( + dataset, /* clear */ false), + keyedScalars: Services.telemetry.snapshotKeyedScalars( + dataset, /* clear */ false), + }; + + if (!snapshots.histograms || !snapshots.keyedHistograms || + !snapshots.scalars || !snapshots.keyedScalars) { + aCallback.onError(`Failed retrieving snapshots!`); + return; + } + + if (aClear) { + Services.telemetry.clearProbes(); } aCallback.onSuccess(snapshots); }, };
--- a/xpcom/base/nsISupportsImpl.h +++ b/xpcom/base/nsISupportsImpl.h @@ -34,22 +34,16 @@ "Make this class's destructor non-public"); inline nsISupports* ToSupports(nsISupports* aSupports) { return aSupports; } -inline nsISupports* -ToCanonicalSupports(nsISupports* aSupports) -{ - return nullptr; -} - //////////////////////////////////////////////////////////////////////////////// // Macros to help detect thread-safety: #ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED #include "prthread.h" /* needed for thread-safety checks */ class nsAutoOwningThread
--- a/xpcom/components/nsIClassInfo.idl +++ b/xpcom/components/nsIClassInfo.idl @@ -56,22 +56,16 @@ interface nsIClassInfo : nsISupports */ const uint32_t SINGLETON = 1 << 0; const uint32_t THREADSAFE = 1 << 1; const uint32_t MAIN_THREAD_ONLY = 1 << 2; const uint32_t DOM_OBJECT = 1 << 3; const uint32_t PLUGIN_OBJECT = 1 << 4; const uint32_t SINGLETON_CLASSINFO = 1 << 5; - /** - * 'flags' attribute bitflag: whether objects of this type implement - * nsIContent. - */ - const uint32_t CONTENT_NODE = 1 << 6; - // The high order bit is RESERVED for consumers of these flags. // No implementor of this interface should ever return flags // with this bit set. const uint32_t RESERVED = 1 << 31; readonly attribute uint32_t flags;
--- a/xpcom/xpidl/Makefile.in +++ b/xpcom/xpidl/Makefile.in @@ -1,10 +1,9 @@ # This Source Code Form is subject to the terms of the Mozilla Public # 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/. export:: - $(call py_action,process_install_manifest,--track install-xpidl.track $(DIST)/idl $(DEPTH)/_build_manifests/install/dist_idl) $(call SUBMAKE,xpidl,$(DEPTH)/config/makefiles/xpidl) clean clobber realclean clobber_all distclean:: $(call SUBMAKE,$@,$(DEPTH)/config/makefiles/xpidl)