From 1e38828c16853b81b2817f701dd0baceb4359a75 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Tue, 26 Jan 2016 11:22:56 +0800 Subject: [PATCH 001/218] Bug 1242839 - Rewrite and enable test_preload_suspend.html. r=roc. --- dom/media/test/mochitest.ini | 1 - dom/media/test/test_preload_suspend.html | 156 +++++++++++++---------- 2 files changed, 89 insertions(+), 68 deletions(-) diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index eba032d2695..84ac2aeed39 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -763,7 +763,6 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439 [test_preload_actions.html] [test_preload_attribute.html] [test_preload_suspend.html] -skip-if = true # bug 493692 [test_progress.html] skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439 [test_reactivate.html] diff --git a/dom/media/test/test_preload_suspend.html b/dom/media/test/test_preload_suspend.html index fface25a656..4a94784622c 100644 --- a/dom/media/test/test_preload_suspend.html +++ b/dom/media/test/test_preload_suspend.html @@ -1,89 +1,111 @@ - Test for Bug 479863 + -Mozilla Bug 479863 -

- - - - - - - - -
-
 
From c3a4a1bd231a4f73207ddb64825bcd913e89e9f5 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 27 Jan 2016 16:58:53 +1100 Subject: [PATCH 002/218] Bug 1229437 part 1 - Add a helper function to get the float containing block of a given frame. r=dbaron --- layout/base/nsLayoutUtils.cpp | 12 ++++++++++++ layout/base/nsLayoutUtils.h | 5 +++++ layout/generic/nsInlineFrame.cpp | 13 +++---------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 5383198e045..fba2abe972e 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -8906,6 +8906,18 @@ nsLayoutUtils::IsScrollFrameWithSnapping(nsIFrame* aFrame) styles.mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE; } +/* static */ nsBlockFrame* +nsLayoutUtils::GetFloatContainingBlock(nsIFrame* aFrame) +{ + nsIFrame* ancestor = aFrame->GetParent(); + while (ancestor && !ancestor->IsFloatContainingBlock()) { + ancestor = ancestor->GetParent(); + } + MOZ_ASSERT(!ancestor || GetAsBlock(ancestor), + "Float containing block can only be block frame"); + return static_cast(ancestor); +} + // The implementation of this calculation is adapted from // Element::GetBoundingClientRect(). /* static */ CSSRect diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 32853d8047d..ad6da6fb729 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2779,6 +2779,11 @@ public: static CSSRect GetBoundingContentRect(const nsIContent* aContent, const nsIScrollableFrame* aRootScrollFrame); + /** + * Returns the first ancestor who is a float containing block. + */ + static nsBlockFrame* GetFloatContainingBlock(nsIFrame* aFrame); + private: static uint32_t sFontSizeInflationEmPerLine; static uint32_t sFontSizeInflationMinTwips; diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 190e3678b1c..dbafb16a387 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -316,20 +316,13 @@ nsInlineFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer, return; } - nsIFrame* ancestor = aFrame; - do { - ancestor = ancestor->GetParent(); - if (!ancestor) - return; - } while (!ancestor->IsFloatContainingBlock()); - - if (ancestor == aOurLineContainer) + nsBlockFrame* frameBlock = nsLayoutUtils::GetFloatContainingBlock(aFrame); + if (!frameBlock || frameBlock == aOurLineContainer) { return; + } nsBlockFrame* ourBlock = nsLayoutUtils::GetAsBlock(aOurLineContainer); NS_ASSERTION(ourBlock, "Not a block, but broke vertically?"); - nsBlockFrame* frameBlock = nsLayoutUtils::GetAsBlock(ancestor); - NS_ASSERTION(frameBlock, "ancestor not a block"); while (true) { ourBlock->ReparentFloats(aFrame, frameBlock, false); From fae15a5608b758bed930d144196f2c5f4632d559 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 27 Jan 2016 16:58:53 +1100 Subject: [PATCH 003/218] Bug 1229437 part 2 - Reparent floats inside pulled ruby segment. r=dbaron --- layout/generic/nsRubyFrame.cpp | 20 +++++++++++++++++--- layout/generic/nsRubyFrame.h | 3 ++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index 70a6592837f..9872e209580 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -142,7 +142,8 @@ nsRubyFrame::Reflow(nsPresContext* aPresContext, ContinuationTraversingState pullState(this); while (aStatus == NS_FRAME_COMPLETE) { - nsRubyBaseContainerFrame* baseContainer = PullOneSegment(pullState); + nsRubyBaseContainerFrame* baseContainer = + PullOneSegment(aReflowState.mLineLayout, pullState); if (!baseContainer) { // No more continuations after, finish now. break; @@ -349,15 +350,21 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, } nsRubyBaseContainerFrame* -nsRubyFrame::PullOneSegment(ContinuationTraversingState& aState) +nsRubyFrame::PullOneSegment(const nsLineLayout* aLineLayout, + ContinuationTraversingState& aState) { // Pull a ruby base container - nsIFrame* baseFrame = PullNextInFlowChild(aState); + nsIFrame* baseFrame = GetNextInFlowChild(aState); if (!baseFrame) { return nullptr; } MOZ_ASSERT(baseFrame->GetType() == nsGkAtoms::rubyBaseContainerFrame); + // Get the float containing block of the base frame before we pull it. + nsBlockFrame* oldFloatCB = + nsLayoutUtils::GetFloatContainingBlock(baseFrame); + PullNextInFlowChild(aState); + // Pull all ruby text containers following the base container nsIFrame* nextFrame; while ((nextFrame = GetNextInFlowChild(aState)) != nullptr && @@ -365,5 +372,12 @@ nsRubyFrame::PullOneSegment(ContinuationTraversingState& aState) PullNextInFlowChild(aState); } + if (nsBlockFrame* newFloatCB = + nsLayoutUtils::GetAsBlock(aLineLayout->LineContainerFrame())) { + if (oldFloatCB && oldFloatCB != newFloatCB) { + newFloatCB->ReparentFloats(baseFrame, oldFloatCB, true); + } + } + return static_cast(baseFrame); } diff --git a/layout/generic/nsRubyFrame.h b/layout/generic/nsRubyFrame.h index ab84de7326c..125c08afac0 100644 --- a/layout/generic/nsRubyFrame.h +++ b/layout/generic/nsRubyFrame.h @@ -62,7 +62,8 @@ protected: nsRubyBaseContainerFrame* aBaseContainer, nsReflowStatus& aStatus); - nsRubyBaseContainerFrame* PullOneSegment(ContinuationTraversingState& aState); + nsRubyBaseContainerFrame* PullOneSegment(const nsLineLayout* aLineLayout, + ContinuationTraversingState& aState); // The leading required to put the annotations. // They are not initialized until the first reflow. From 40b5e3836439bdc3dd1e817005f0916492c20000 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 27 Jan 2016 16:58:53 +1100 Subject: [PATCH 004/218] Bug 1229437 part 3 - Support iterating frames of RubyColumn. r=dholbert --- layout/generic/RubyUtils.cpp | 29 ++++++++++++++++++++++ layout/generic/RubyUtils.h | 47 ++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/layout/generic/RubyUtils.cpp b/layout/generic/RubyUtils.cpp index e99e79f01d8..f3b09f6fb2f 100644 --- a/layout/generic/RubyUtils.cpp +++ b/layout/generic/RubyUtils.cpp @@ -57,6 +57,35 @@ AutoRubyTextContainerArray::AutoRubyTextContainerArray( } } +nsIFrame* +RubyColumn::Iterator::operator*() const +{ + nsIFrame* frame; + if (mIndex == -1) { + frame = mColumn.mBaseFrame; + } else { + frame = mColumn.mTextFrames[mIndex]; + } + MOZ_ASSERT(frame, "Frame here cannot be null"); + return frame; +} + +void +RubyColumn::Iterator::SkipUntilExistingFrame() +{ + if (mIndex == -1) { + if (!mColumn.mBaseFrame) { + ++mIndex; + } + } + auto numTextFrames = mColumn.mTextFrames.Length(); + for (; mIndex < numTextFrames; ++mIndex) { + if (mColumn.mTextFrames[mIndex]) { + break; + } + } +} + RubySegmentEnumerator::RubySegmentEnumerator(nsRubyFrame* aRubyFrame) { nsIFrame* frame = aRubyFrame->GetFirstPrincipalChild(); diff --git a/layout/generic/RubyUtils.h b/layout/generic/RubyUtils.h index 886acf79580..219f91e1979 100644 --- a/layout/generic/RubyUtils.h +++ b/layout/generic/RubyUtils.h @@ -133,7 +133,54 @@ struct MOZ_STACK_CLASS RubyColumn nsRubyBaseFrame* mBaseFrame; nsAutoTArray mTextFrames; bool mIsIntraLevelWhitespace; + RubyColumn() : mBaseFrame(nullptr), mIsIntraLevelWhitespace(false) { } + + // Helper class to support iteration across the frames within a single + // RubyColumn (the column's ruby base and its annotations). + class MOZ_STACK_CLASS Iterator + { + public: + nsIFrame* operator*() const; + + Iterator& operator++() { ++mIndex; SkipUntilExistingFrame(); return *this; } + Iterator operator++(int) { auto ret = *this; ++*this; return ret; } + + friend bool operator==(const Iterator& aIter1, const Iterator& aIter2) + { + MOZ_ASSERT(&aIter1.mColumn == &aIter2.mColumn, + "Should only compare iterators of the same ruby column"); + return aIter1.mIndex == aIter2.mIndex; + } + friend bool operator!=(const Iterator& aIter1, const Iterator& aIter2) + { + return !(aIter1 == aIter2); + } + + private: + Iterator(const RubyColumn& aColumn, int32_t aIndex) + : mColumn(aColumn) + , mIndex(aIndex) + { + MOZ_ASSERT(aIndex == -1 || + (aIndex >= 0 && aIndex <= aColumn.mTextFrames.Length())); + SkipUntilExistingFrame(); + } + friend struct RubyColumn; // for the constructor + + void SkipUntilExistingFrame(); + + const RubyColumn& mColumn; + // -1 means the ruby base frame, + // non-negative means the index of ruby text frame + // a value of mTextFrames.Length() means we're done iterating + int32_t mIndex = -1; + }; + + Iterator begin() const { return Iterator(*this, -1); } + Iterator end() const { return Iterator(*this, mTextFrames.Length()); } + Iterator cbegin() const { return begin(); } + Iterator cend() const { return end(); } }; /** From a7acdef2e922221c03536c35d635e48afedc8e4f Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 27 Jan 2016 16:58:53 +1100 Subject: [PATCH 005/218] Bug 1229437 part 4 - Reparent floats inside pulled ruby column. r=dbaron --- layout/generic/nsRubyBaseContainerFrame.cpp | 37 ++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 67a65953600..047e0cd27ae 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -724,7 +724,7 @@ nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout, nsIFrame* nextBase = GetNextInFlowChild(aPullFrameState.mBase); MOZ_ASSERT(!nextBase || nextBase->GetType() == nsGkAtoms::rubyBaseFrame); aColumn.mBaseFrame = static_cast(nextBase); - aIsComplete = !aColumn.mBaseFrame; + bool foundFrame = !!aColumn.mBaseFrame; bool pullingIntraLevelWhitespace = aColumn.mBaseFrame && aColumn.mBaseFrame->IsIntraLevelWhitespace(); @@ -735,13 +735,17 @@ nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout, MOZ_ASSERT(!nextText || nextText->GetType() == nsGkAtoms::rubyTextFrame); nsRubyTextFrame* textFrame = static_cast(nextText); aColumn.mTextFrames.AppendElement(textFrame); - // If there exists any frame in continations, we haven't - // completed the reflow process. - aIsComplete = aIsComplete && !nextText; + foundFrame = foundFrame || nextText; if (nextText && !pullingIntraLevelWhitespace) { pullingIntraLevelWhitespace = textFrame->IsIntraLevelWhitespace(); } } + // If there exists any frame in continations, we haven't + // completed the reflow process. + aIsComplete = !foundFrame; + if (!foundFrame) { + return; + } aColumn.mIsIntraLevelWhitespace = pullingIntraLevelWhitespace; if (pullingIntraLevelWhitespace) { @@ -757,6 +761,31 @@ nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout, textFrame = nullptr; } } + } else { + // We are not pulling an intra-level whitespace, which means all + // elements we are going to pull can have non-whitespace content, + // which may contain float which we need to reparent. + nsBlockFrame* oldFloatCB = nullptr; + for (nsIFrame* frame : aColumn) { + oldFloatCB = nsLayoutUtils::GetFloatContainingBlock(frame); + break; + } +#ifdef DEBUG + MOZ_ASSERT(oldFloatCB, "Must have found a float containing block"); + for (nsIFrame* frame : aColumn) { + MOZ_ASSERT(nsLayoutUtils::GetFloatContainingBlock(frame) == oldFloatCB, + "All frames in the same ruby column should share " + "the same old float containing block"); + } +#endif + nsBlockFrame* newFloatCB = + nsLayoutUtils::GetAsBlock(aLineLayout->LineContainerFrame()); + MOZ_ASSERT(newFloatCB, "Must have a float containing block"); + if (oldFloatCB != newFloatCB) { + for (nsIFrame* frame : aColumn) { + newFloatCB->ReparentFloats(frame, oldFloatCB, false); + } + } } // Pull the frames of this column. From faf4dac2df2f5c45b00b861e25687448648c24a5 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 27 Jan 2016 16:58:53 +1100 Subject: [PATCH 006/218] Bug 1229437 part 5 - Add crashtests for this bug. r=dbaron --- layout/generic/crashtests/1229437-1.html | 8 ++++++++ layout/generic/crashtests/1229437-2.html | 5 +++++ layout/generic/crashtests/crashtests.list | 2 ++ 3 files changed, 15 insertions(+) create mode 100644 layout/generic/crashtests/1229437-1.html create mode 100644 layout/generic/crashtests/1229437-2.html diff --git a/layout/generic/crashtests/1229437-1.html b/layout/generic/crashtests/1229437-1.html new file mode 100644 index 00000000000..2f1e66c31eb --- /dev/null +++ b/layout/generic/crashtests/1229437-1.html @@ -0,0 +1,8 @@ + + + +
+
X +
diff --git a/layout/generic/crashtests/1229437-2.html b/layout/generic/crashtests/1229437-2.html new file mode 100644 index 00000000000..5b6ce632943 --- /dev/null +++ b/layout/generic/crashtests/1229437-2.html @@ -0,0 +1,5 @@ + + +
+
X +
diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index e584a591026..ad8f55b6e4f 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -600,6 +600,8 @@ load 1224230-1.html pref(layout.css.grid.enabled,true) load 1225118.html pref(layout.css.grid.enabled,true) load 1225376.html pref(layout.css.grid.enabled,true) load 1225592.html +load 1229437-1.html +load 1229437-2.html load first-letter-638937-1.html load first-letter-638937-2.html pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) asserts(0-100) load font-inflation-762332.html # bug 762332 From 647125db4cac2a7e973bc42a8aa9ec338efa3a63 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 27 Jan 2016 15:09:13 +0900 Subject: [PATCH 007/218] Bug 1242895 Put off to commit/cancel composition after unlocking the document in TSF mode r=m_kato --- widget/windows/TSFTextStore.cpp | 59 ++++++++++++++++++++++++++++----- widget/windows/TSFTextStore.h | 6 ++++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/widget/windows/TSFTextStore.cpp b/widget/windows/TSFTextStore.cpp index 7bb4424ed9a..83f6aae830c 100644 --- a/widget/windows/TSFTextStore.cpp +++ b/widget/windows/TSFTextStore.cpp @@ -1321,6 +1321,8 @@ TSFTextStore::TSFTextStore() , mDeferClearingLockedContent(false) , mNativeCaretIsCreated(false) , mDeferNotifyingTSF(false) + , mDeferCommittingComposition(false) + , mDeferCancellingComposition(false) , mDestroyed(false) { for (int32_t i = 0; i < NUM_OF_SUPPORTED_ATTRS; i++) { @@ -1874,6 +1876,28 @@ TSFTextStore::FlushPendingActions() void TSFTextStore::MaybeFlushPendingNotifications() { + if (IsReadLocked()) { + MOZ_LOG(sTextStoreLog, LogLevel::Debug, + ("TSF: 0x%p TSFTextStore::MaybeFlushPendingNotifications(), " + "putting off flushing pending notifications due to being the " + "document locked...", this)); + return; + } + + if (mDeferCommittingComposition) { + MOZ_LOG(sTextStoreLog, LogLevel::Info, + ("TSF: 0x%p TSFTextStore::MaybeFlushPendingNotifications(), " + "calling TSFTextStore::CommitCompositionInternal(false)...", this)); + mDeferCommittingComposition = mDeferCancellingComposition = false; + CommitCompositionInternal(false); + } else if (mDeferCancellingComposition) { + MOZ_LOG(sTextStoreLog, LogLevel::Info, + ("TSF: 0x%p TSFTextStore::MaybeFlushPendingNotifications(), " + "calling TSFTextStore::CommitCompositionInternal(true)...", this)); + mDeferCommittingComposition = mDeferCancellingComposition = false; + CommitCompositionInternal(true); + } + if (mDeferNotifyingTSF) { MOZ_LOG(sTextStoreLog, LogLevel::Debug, ("TSF: 0x%p TSFTextStore::MaybeFlushPendingNotifications(), " @@ -1882,14 +1906,6 @@ TSFTextStore::MaybeFlushPendingNotifications() return; } - if (IsReadLocked()) { - MOZ_LOG(sTextStoreLog, LogLevel::Debug, - ("TSF: 0x%p TSFTextStore::MaybeFlushPendingNotifications(), " - "putting off flushing pending notifications due to being the " - "document locked...", this)); - return; - } - if (mPendingDestroy) { Destroy(); return; @@ -5121,10 +5137,35 @@ TSFTextStore::CommitCompositionInternal(bool aDiscard) mComposition.mView.get(), NS_ConvertUTF16toUTF8(mComposition.mString).get())); + // If the document is locked, TSF will fail to commit composition since + // TSF needs another document lock. So, let's put off the request. + // Note that TextComposition will commit composition in the focused editor + // with the latest composition string for web apps and waits asynchronous + // committing messages. Therefore, we can and need to perform this + // asynchronously. + if (IsReadLocked()) { + if (mDeferCommittingComposition || mDeferCancellingComposition) { + MOZ_LOG(sTextStoreLog, LogLevel::Debug, + ("TSF: 0x%p TSFTextStore::CommitCompositionInternal(), " + "does nothing because already called and waiting unlock...", this)); + return; + } + if (aDiscard) { + mDeferCancellingComposition = true; + } else { + mDeferCommittingComposition = true; + } + MOZ_LOG(sTextStoreLog, LogLevel::Debug, + ("TSF: 0x%p TSFTextStore::CommitCompositionInternal(), " + "putting off to request to %s composition after unlocking the document", + this, aDiscard ? "cancel" : "commit")); + return; + } + if (mComposition.IsComposing() && aDiscard) { LONG endOffset = mComposition.EndOffset(); mComposition.mString.Truncate(0); - if (mSink && !mLock) { + if (mSink) { TS_TEXTCHANGE textChange; textChange.acpStart = mComposition.mStart; textChange.acpOldEnd = endOffset; diff --git a/widget/windows/TSFTextStore.h b/widget/windows/TSFTextStore.h index eb8e5a55713..2eb994d6647 100644 --- a/widget/windows/TSFTextStore.h +++ b/widget/windows/TSFTextStore.h @@ -852,6 +852,12 @@ protected: // For preventing it to be called, we should put off notifying TSF of // anything until layout information becomes available. bool mDeferNotifyingTSF; + // While the document is locked, committing composition always fails since + // TSF needs another document lock for modifying the composition, selection + // and etc. So, committing composition should be performed after the + // document is unlocked. + bool mDeferCommittingComposition; + bool mDeferCancellingComposition; // Immediately after a call of Destroy(), mDestroyed becomes true. If this // is true, the instance shouldn't grant any requests from the TIP anymore. bool mDestroyed; From 3b90838075e0e8fa964e134d619ace2ff82461eb Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 27 Jan 2016 15:09:13 +0900 Subject: [PATCH 008/218] Bug 1153156 part.1 Move nsBaseWidget::OverrideSystemMouseScrollSpeed() to WidgetWheelEvent r=smaug, sr=smaug --- dom/events/WheelHandlingHelper.cpp | 14 ++------ widget/MouseEvents.h | 18 ++++++++++ widget/WidgetEventImpl.cpp | 54 ++++++++++++++++++++++++++++++ widget/nsBaseWidget.cpp | 45 ------------------------- widget/nsBaseWidget.h | 4 --- widget/nsIWidget.h | 30 ++--------------- widget/windows/nsWindow.cpp | 2 ++ widget/windows/nsWindow.h | 5 --- 8 files changed, 78 insertions(+), 94 deletions(-) diff --git a/dom/events/WheelHandlingHelper.cpp b/dom/events/WheelHandlingHelper.cpp index 86e74de2f0b..0ac297d882d 100644 --- a/dom/events/WheelHandlingHelper.cpp +++ b/dom/events/WheelHandlingHelper.cpp @@ -419,18 +419,8 @@ WheelTransaction::OverrideSystemScrollSpeed(WidgetWheelEvent* aEvent) return DeltaValues(aEvent); } - // Compute the overridden speed to nsIWidget. The widget can check the - // conditions (e.g., checking the prefs, and also whether the user customized - // the system settings of the mouse wheel scrolling or not), and can limit - // the speed for preventing the unexpected high speed scrolling. - nsCOMPtr widget(sTargetFrame->GetNearestWidget()); - NS_ENSURE_TRUE(widget, DeltaValues(aEvent)); - DeltaValues overriddenDeltaValues(0.0, 0.0); - nsresult rv = - widget->OverrideSystemMouseScrollSpeed(aEvent->deltaX, aEvent->deltaY, - overriddenDeltaValues.deltaX, - overriddenDeltaValues.deltaY); - return NS_FAILED(rv) ? DeltaValues(aEvent) : overriddenDeltaValues; + return DeltaValues(aEvent->OverriddenDeltaX(), + aEvent->OverriddenDeltaY()); } /******************************************************************/ diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h index 5e45007fbdb..40d34c6ebf7 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -619,6 +619,24 @@ public: mViewPortIsOverscrolled = aEvent.mViewPortIsOverscrolled; mCanTriggerSwipe = aEvent.mCanTriggerSwipe; } + + // System scroll speed settings may be too slow at using Gecko. In such + // case, we should override the scroll speed computed with system settings. + // Following methods return preferred delta values which are multiplied by + // factors specified by prefs. If system scroll speed shouldn't be + // overridden (e.g., this feature is disabled by pref), they return raw + // delta values. + double OverriddenDeltaX() const; + double OverriddenDeltaY() const; + +private: + static bool sInitialized; + static bool sIsSystemScrollSpeedOverrideEnabled; + static int32_t sOverrideFactorX; + static int32_t sOverrideFactorY; + static void Initialize(); + + static double ComputeOverriddenDelta(double aDelta, bool aIsForVertical); }; /****************************************************************************** diff --git a/widget/WidgetEventImpl.cpp b/widget/WidgetEventImpl.cpp index 6850a612cb0..a828a8e9800 100644 --- a/widget/WidgetEventImpl.cpp +++ b/widget/WidgetEventImpl.cpp @@ -339,6 +339,60 @@ WidgetInputEvent::AccelModifier() return sAccelModifier; } +/****************************************************************************** + * mozilla::WidgetWheelEvent (MouseEvents.h) + ******************************************************************************/ + +bool WidgetWheelEvent::sInitialized = false; +bool WidgetWheelEvent::sIsSystemScrollSpeedOverrideEnabled = false; +int32_t WidgetWheelEvent::sOverrideFactorX = 0; +int32_t WidgetWheelEvent::sOverrideFactorY = 0; + +/* static */ void +WidgetWheelEvent::Initialize() +{ + if (sInitialized) { + return; + } + + Preferences::AddBoolVarCache(&sIsSystemScrollSpeedOverrideEnabled, + "mousewheel.system_scroll_override_on_root_content.enabled", false); + Preferences::AddIntVarCache(&sOverrideFactorX, + "mousewheel.system_scroll_override_on_root_content.horizontal.factor", 0); + Preferences::AddIntVarCache(&sOverrideFactorY, + "mousewheel.system_scroll_override_on_root_content.vertical.factor", 0); + sInitialized = true; +} + +/* static */ double +WidgetWheelEvent::ComputeOverriddenDelta(double aDelta, bool aIsForVertical) +{ + Initialize(); + if (!sIsSystemScrollSpeedOverrideEnabled) { + return aDelta; + } + int32_t intFactor = aIsForVertical ? sOverrideFactorY : sOverrideFactorX; + // Making the scroll speed slower doesn't make sense. So, ignore odd factor + // which is less than 1.0. + if (intFactor <= 100) { + return aDelta; + } + double factor = static_cast(intFactor) / 100; + return aDelta * factor; +} + +double +WidgetWheelEvent::OverriddenDeltaX() const +{ + return ComputeOverriddenDelta(deltaX, false); +} + +double +WidgetWheelEvent::OverriddenDeltaY() const +{ + return ComputeOverriddenDelta(deltaY, true); +} + /****************************************************************************** * mozilla::WidgetKeyboardEvent (TextEvents.h) ******************************************************************************/ diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index 54cd58c0606..875fe180350 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -1527,51 +1527,6 @@ nsBaseWidget::ShowsResizeIndicator(LayoutDeviceIntRect* aResizerRect) return false; } -NS_IMETHODIMP -nsBaseWidget::OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, - double aOriginalDeltaY, - double& aOverriddenDeltaX, - double& aOverriddenDeltaY) -{ - aOverriddenDeltaX = aOriginalDeltaX; - aOverriddenDeltaY = aOriginalDeltaY; - - static bool sInitialized = false; - static bool sIsOverrideEnabled = false; - static int32_t sIntFactorX = 0; - static int32_t sIntFactorY = 0; - - if (!sInitialized) { - Preferences::AddBoolVarCache(&sIsOverrideEnabled, - "mousewheel.system_scroll_override_on_root_content.enabled", false); - Preferences::AddIntVarCache(&sIntFactorX, - "mousewheel.system_scroll_override_on_root_content.horizontal.factor", 0); - Preferences::AddIntVarCache(&sIntFactorY, - "mousewheel.system_scroll_override_on_root_content.vertical.factor", 0); - sIntFactorX = std::max(sIntFactorX, 0); - sIntFactorY = std::max(sIntFactorY, 0); - sInitialized = true; - } - - if (!sIsOverrideEnabled) { - return NS_OK; - } - - // The pref value must be larger than 100, otherwise, we don't override the - // delta value. - if (sIntFactorX > 100) { - double factor = static_cast(sIntFactorX) / 100; - aOverriddenDeltaX *= factor; - } - if (sIntFactorY > 100) { - double factor = static_cast(sIntFactorY) / 100; - aOverriddenDeltaY *= factor; - } - - return NS_OK; -} - - /** * Modifies aFile to point at an icon file with the given name and suffix. The * suffix may correspond to a file extension with leading '.' if appropriate. diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index 6ff115ef856..34729aaa3fd 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -238,10 +238,6 @@ public: virtual bool ComputeShouldAccelerate(); virtual nsIMEUpdatePreference GetIMEUpdatePreference() override { return nsIMEUpdatePreference(); } NS_IMETHOD OnDefaultButtonLoaded(const LayoutDeviceIntRect& aButtonRect) override { return NS_ERROR_NOT_IMPLEMENTED; } - NS_IMETHOD OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, - double aOriginalDeltaY, - double& aOverriddenDeltaX, - double& aOverriddenDeltaY) override; virtual already_AddRefed CreateChild(const LayoutDeviceIntRect& aRect, nsWidgetInitData* aInitData = nullptr, diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 7f098091566..02b31c0b386 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -133,8 +133,8 @@ typedef void* nsNativeWidget; #endif #define NS_IWIDGET_IID \ -{ 0x6dc8ce1f, 0xbb55, 0x47c1, \ - { 0xa1, 0x6f, 0x4e, 0x12, 0x37, 0xa1, 0xc2, 0xf4 } } +{ 0x06396bf6, 0x2dd8, 0x45e5, \ + { 0xac, 0x45, 0x75, 0x26, 0x53, 0xb1, 0xc9, 0x80 } } /* * Window shadow styles @@ -1896,32 +1896,6 @@ public: */ NS_IMETHOD OnDefaultButtonLoaded(const LayoutDeviceIntRect& aButtonRect) = 0; - /** - * Compute the overridden system mouse scroll speed on the root content of - * web pages. The widget may set the same value as aOriginalDelta. E.g., - * when the system scrolling settings were customized, widget can respect - * the will of the user. - * - * This is called only when the mouse wheel event scrolls the root content - * of the web pages by line. In other words, this isn't called when the - * mouse wheel event is used for zoom, page scroll and other special - * actions. And also this isn't called when the user doesn't use the - * system wheel speed settings. - * - * @param aOriginalDeltaX The X delta value of the current mouse wheel - * scrolling event. - * @param aOriginalDeltaX The Y delta value of the current mouse wheel - * scrolling event. - * @param aOverriddenDeltaX The overridden mouse scrolling speed along X - * axis. This value may be same as aOriginalDeltaX. - * @param aOverriddenDeltaY The overridden mouse scrolling speed along Y - * axis. This value may be same as aOriginalDeltaY. - */ - NS_IMETHOD OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, - double aOriginalDeltaY, - double& aOverriddenDeltaX, - double& aOverriddenDeltaY) = 0; - /** * Return true if this process shouldn't use platform widgets, and * so should use PuppetWidgets instead. If this returns true, the diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 94b8487a2e1..ba2f1e22c42 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -3715,6 +3715,7 @@ nsWindow::OnDefaultButtonLoaded(const LayoutDeviceIntRect& aButtonRect) return NS_OK; } +#if 0 NS_IMETHODIMP nsWindow::OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, double aOriginalDeltaY, @@ -3800,6 +3801,7 @@ nsWindow::OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, } return NS_OK; } +#endif already_AddRefed nsWindow::StartRemoteDrawing() diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 0cd3f6f2c5b..e8021f3a189 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -172,11 +172,6 @@ public: LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, bool* aAllowRetaining = nullptr) override; NS_IMETHOD OnDefaultButtonLoaded(const LayoutDeviceIntRect& aButtonRect) override; - NS_IMETHOD OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, - double aOriginalDeltaY, - double& aOverriddenDeltaX, - double& aOverriddenDeltaY) override; - virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout, int32_t aNativeKeyCode, uint32_t aModifierFlags, From 6f56a7bd2c83a89e1a20d5a5682cd1215df5536a Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 27 Jan 2016 15:09:13 +0900 Subject: [PATCH 009/218] Bug 1153156 part.2 Make WidgetWheelEvent store if overriding system scroll speed is allowed and it shouldn't be allowed if scroll speed isn't system default settings on Windows r=smaug+jimm --- widget/MouseEvents.h | 9 +++++ widget/WidgetEventImpl.cpp | 6 ++++ widget/nsGUIEventIPC.h | 4 ++- widget/windows/WinMouseScrollHandler.cpp | 38 ++++++++++++++------ widget/windows/WinMouseScrollHandler.h | 10 ++++-- widget/windows/nsWindow.cpp | 46 ------------------------ 6 files changed, 53 insertions(+), 60 deletions(-) diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h index 40d34c6ebf7..9e45104a4f7 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -462,6 +462,7 @@ private: , overflowDeltaY(0.0) , mViewPortIsOverscrolled(false) , mCanTriggerSwipe(false) + , mAllowToOverrideSystemScrollSpeed(false) { } @@ -485,6 +486,7 @@ public: , overflowDeltaY(0.0) , mViewPortIsOverscrolled(false) , mCanTriggerSwipe(false) + , mAllowToOverrideSystemScrollSpeed(true) { } @@ -599,6 +601,11 @@ public: // viewport. bool mCanTriggerSwipe; + // If mAllowToOverrideSystemScrollSpeed is true, the scroll speed may be + // overridden. Otherwise, the scroll speed won't be overridden even if + // it's enabled by the pref. + bool mAllowToOverrideSystemScrollSpeed; + void AssignWheelEventData(const WidgetWheelEvent& aEvent, bool aCopyTargets) { AssignMouseEventBaseData(aEvent, aCopyTargets); @@ -618,6 +625,8 @@ public: overflowDeltaY = aEvent.overflowDeltaY; mViewPortIsOverscrolled = aEvent.mViewPortIsOverscrolled; mCanTriggerSwipe = aEvent.mCanTriggerSwipe; + mAllowToOverrideSystemScrollSpeed = + aEvent.mAllowToOverrideSystemScrollSpeed; } // System scroll speed settings may be too slow at using Gecko. In such diff --git a/widget/WidgetEventImpl.cpp b/widget/WidgetEventImpl.cpp index a828a8e9800..cdddd94083d 100644 --- a/widget/WidgetEventImpl.cpp +++ b/widget/WidgetEventImpl.cpp @@ -384,12 +384,18 @@ WidgetWheelEvent::ComputeOverriddenDelta(double aDelta, bool aIsForVertical) double WidgetWheelEvent::OverriddenDeltaX() const { + if (!mAllowToOverrideSystemScrollSpeed) { + return deltaX; + } return ComputeOverriddenDelta(deltaX, false); } double WidgetWheelEvent::OverriddenDeltaY() const { + if (!mAllowToOverrideSystemScrollSpeed) { + return deltaY; + } return ComputeOverriddenDelta(deltaY, true); } diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index 424b9401787..840c262bb9d 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -175,6 +175,7 @@ struct ParamTraits WriteParam(aMsg, aParam.overflowDeltaY); WriteParam(aMsg, aParam.mViewPortIsOverscrolled); WriteParam(aMsg, aParam.mCanTriggerSwipe); + WriteParam(aMsg, aParam.mAllowToOverrideSystemScrollSpeed); } static bool Read(const Message* aMsg, void** aIter, paramType* aResult) @@ -197,7 +198,8 @@ struct ParamTraits ReadParam(aMsg, aIter, &aResult->overflowDeltaX) && ReadParam(aMsg, aIter, &aResult->overflowDeltaY) && ReadParam(aMsg, aIter, &aResult->mViewPortIsOverscrolled) && - ReadParam(aMsg, aIter, &aResult->mCanTriggerSwipe); + ReadParam(aMsg, aIter, &aResult->mCanTriggerSwipe) && + ReadParam(aMsg, aIter, &aResult->mAllowToOverrideSystemScrollSpeed); aResult->scrollType = static_cast(scrollType); return rv; diff --git a/widget/windows/WinMouseScrollHandler.cpp b/widget/windows/WinMouseScrollHandler.cpp index 4987d53fd65..3dee8fe7688 100644 --- a/widget/windows/WinMouseScrollHandler.cpp +++ b/widget/windows/WinMouseScrollHandler.cpp @@ -613,7 +613,7 @@ MouseScrollHandler::HandleMouseWheelMessage(nsWindowBase* aWidget, // If it's not allowed to cache system settings, we need to reset the cache // before handling the mouse wheel message. - mSystemSettings.TrustedScrollSettingsDriver(aMessage == MOZ_WM_MOUSEVWHEEL); + mSystemSettings.TrustedScrollSettingsDriver(); EventInfo eventInfo(aWidget, WinUtils::GetNativeMessage(aMessage), aWParam, aLParam); @@ -863,11 +863,16 @@ MouseScrollHandler::LastEventInfo::InitWheelEvent( mAccumulatedDelta -= lineOrPageDelta * orienter * RoundDelta(nativeDeltaPerUnit); + aWheelEvent.mAllowToOverrideSystemScrollSpeed = + MouseScrollHandler::sInstance-> + mSystemSettings.IsOverridingSystemScrollSpeedAllowed(); + MOZ_LOG(gMouseScrollLog, LogLevel::Info, ("MouseScroll::LastEventInfo::InitWheelEvent: aWidget=%p, " "aWheelEvent { refPoint: { x: %d, y: %d }, deltaX: %f, deltaY: %f, " "lineOrPageDeltaX: %d, lineOrPageDeltaY: %d, " - "isShift: %s, isControl: %s, isAlt: %s, isMeta: %s }, " + "isShift: %s, isControl: %s, isAlt: %s, isMeta: %s, " + "mAllowToOverrideSystemScrollSpeed: %s }, " "mAccumulatedDelta: %d", aWidget, aWheelEvent.refPoint.x, aWheelEvent.refPoint.y, aWheelEvent.deltaX, aWheelEvent.deltaY, @@ -875,7 +880,9 @@ MouseScrollHandler::LastEventInfo::InitWheelEvent( GetBoolName(aWheelEvent.IsShift()), GetBoolName(aWheelEvent.IsControl()), GetBoolName(aWheelEvent.IsAlt()), - GetBoolName(aWheelEvent.IsMeta()), mAccumulatedDelta)); + GetBoolName(aWheelEvent.IsMeta()), + GetBoolName(aWheelEvent.mAllowToOverrideSystemScrollSpeed), + mAccumulatedDelta)); return (delta != 0); } @@ -994,9 +1001,10 @@ MouseScrollHandler::SystemSettings::MarkDirty() } void -MouseScrollHandler::SystemSettings::RefreshCache(bool aForVertical) +MouseScrollHandler::SystemSettings::RefreshCache() { - bool isChanged = aForVertical ? InitScrollLines() : InitScrollChars(); + bool isChanged = InitScrollLines(); + isChanged = InitScrollChars() || isChanged; if (!isChanged) { return; } @@ -1007,16 +1015,14 @@ MouseScrollHandler::SystemSettings::RefreshCache(bool aForVertical) } void -MouseScrollHandler::SystemSettings::TrustedScrollSettingsDriver( - bool aIsVertical) +MouseScrollHandler::SystemSettings::TrustedScrollSettingsDriver() { if (!mInitialized) { return; } // if the cache is initialized with prefs, we don't need to refresh it. - if ((aIsVertical && mIsReliableScrollLines) || - (!aIsVertical && mIsReliableScrollChars)) { + if (mIsReliableScrollLines && mIsReliableScrollChars) { return; } @@ -1025,7 +1031,7 @@ MouseScrollHandler::SystemSettings::TrustedScrollSettingsDriver( // If system settings cache is disabled, we should always refresh them. if (!userPrefs.IsSystemSettingCacheEnabled()) { - RefreshCache(aIsVertical); + RefreshCache(); return; } @@ -1039,13 +1045,23 @@ MouseScrollHandler::SystemSettings::TrustedScrollSettingsDriver( // ::SystemParametersInfo() and returns different value from system settings. if (Device::SynTP::IsDriverInstalled() || Device::Apoint::IsDriverInstalled()) { - RefreshCache(aIsVertical); + RefreshCache(); return; } // XXX We're not sure about other touchpad drivers... } +bool +MouseScrollHandler::SystemSettings::IsOverridingSystemScrollSpeedAllowed() +{ + // The default vertical and horizontal scrolling speed is 3, this is defined + // on the document of SystemParametersInfo in MSDN. + const uint32_t kSystemDefaultScrollingSpeed = 3; + return mScrollLines == kSystemDefaultScrollingSpeed && + (!IsVistaOrLater() || mScrollChars == kSystemDefaultScrollingSpeed); +} + /****************************************************************************** * * UserPrefs diff --git a/widget/windows/WinMouseScrollHandler.h b/widget/windows/WinMouseScrollHandler.h index ccfa68fc5eb..506bb6ada40 100644 --- a/widget/windows/WinMouseScrollHandler.h +++ b/widget/windows/WinMouseScrollHandler.h @@ -279,7 +279,13 @@ private: // changed without WM_SETTINGCHANGE message. For avoiding this trouble, // we need to modify cache of system settings at every wheel message // handling if we meet known device whose utility may hook the API. - void TrustedScrollSettingsDriver(bool aIsVertical); + void TrustedScrollSettingsDriver(); + + // Returns true if the system scroll may be overridden for faster scroll. + // Otherwise, false. For example, if the user maybe uses an expensive + // mouse which supports acceleration of scroll speed, faster scroll makes + // the user inconvenient. + bool IsOverridingSystemScrollSpeedAllowed(); int32_t GetScrollAmount(bool aForVertical) const { @@ -310,7 +316,7 @@ private: bool InitScrollLines(); bool InitScrollChars(); - void RefreshCache(bool aForVertical); + void RefreshCache(); }; SystemSettings mSystemSettings; diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index ba2f1e22c42..5ff592e66a3 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -3726,52 +3726,6 @@ nsWindow::OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, // on the document of SystemParametersInfo in MSDN. const uint32_t kSystemDefaultScrollingSpeed = 3; - double absOriginDeltaX = Abs(aOriginalDeltaX); - double absOriginDeltaY = Abs(aOriginalDeltaY); - - // Compute the simple overridden speed. - double absComputedOverriddenDeltaX, absComputedOverriddenDeltaY; - nsresult rv = - nsBaseWidget::OverrideSystemMouseScrollSpeed(absOriginDeltaX, - absOriginDeltaY, - absComputedOverriddenDeltaX, - absComputedOverriddenDeltaY); - NS_ENSURE_SUCCESS(rv, rv); - - aOverriddenDeltaX = aOriginalDeltaX; - aOverriddenDeltaY = aOriginalDeltaY; - - if (absComputedOverriddenDeltaX == absOriginDeltaX && - absComputedOverriddenDeltaY == absOriginDeltaY) { - // We don't override now. - return NS_OK; - } - - // Otherwise, we should check whether the user customized the system settings - // or not. If the user did it, we should respect the will. - UINT systemSpeed; - if (!::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &systemSpeed, 0)) { - return NS_ERROR_FAILURE; - } - // The default vertical scrolling speed is 3, this is defined on the document - // of SystemParametersInfo in MSDN. - if (systemSpeed != kSystemDefaultScrollingSpeed) { - return NS_OK; - } - - // Only Vista and later, Windows has the system setting of horizontal - // scrolling by the mouse wheel. - if (IsVistaOrLater()) { - if (!::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &systemSpeed, 0)) { - return NS_ERROR_FAILURE; - } - // The default horizontal scrolling speed is 3, this is defined on the - // document of SystemParametersInfo in MSDN. - if (systemSpeed != kSystemDefaultScrollingSpeed) { - return NS_OK; - } - } - // Limit the overridden delta value from the system settings. The mouse // driver might accelerate the scrolling speed already. If so, we shouldn't // override the scrolling speed for preventing the unexpected high speed From 95c2b8dfcc890eb1047634031e2b73cee237a279 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 27 Jan 2016 15:09:13 +0900 Subject: [PATCH 010/218] Bug 1153156 part.3 Don't allow to override system scroll speed if the wheel event causes too fast scroll r=smaug+jimm --- widget/MouseEvents.h | 7 ++-- widget/windows/WinMouseScrollHandler.cpp | 43 +++++++++++++++++++----- widget/windows/WinMouseScrollHandler.h | 5 +++ widget/windows/nsWindow.cpp | 42 ----------------------- 4 files changed, 44 insertions(+), 53 deletions(-) diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h index 9e45104a4f7..d6b36238694 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -638,14 +638,17 @@ public: double OverriddenDeltaX() const; double OverriddenDeltaY() const; + // Compute the overridden delta value. This may be useful for suppressing + // too fast scroll by system scroll speed overriding when widget sets + // mAllowToOverrideSystemScrollSpeed. + static double ComputeOverriddenDelta(double aDelta, bool aIsForVertical); + private: static bool sInitialized; static bool sIsSystemScrollSpeedOverrideEnabled; static int32_t sOverrideFactorX; static int32_t sOverrideFactorY; static void Initialize(); - - static double ComputeOverriddenDelta(double aDelta, bool aIsForVertical); }; /****************************************************************************** diff --git a/widget/windows/WinMouseScrollHandler.cpp b/widget/windows/WinMouseScrollHandler.cpp index 3dee8fe7688..e11c2e4f540 100644 --- a/widget/windows/WinMouseScrollHandler.cpp +++ b/widget/windows/WinMouseScrollHandler.cpp @@ -863,9 +863,36 @@ MouseScrollHandler::LastEventInfo::InitWheelEvent( mAccumulatedDelta -= lineOrPageDelta * orienter * RoundDelta(nativeDeltaPerUnit); - aWheelEvent.mAllowToOverrideSystemScrollSpeed = - MouseScrollHandler::sInstance-> - mSystemSettings.IsOverridingSystemScrollSpeedAllowed(); + if (aWheelEvent.deltaMode != nsIDOMWheelEvent::DOM_DELTA_LINE) { + // If the scroll delta mode isn't per line scroll, we shouldn't allow to + // override the system scroll speed setting. + aWheelEvent.mAllowToOverrideSystemScrollSpeed = false; + } else if (!MouseScrollHandler::sInstance-> + mSystemSettings.IsOverridingSystemScrollSpeedAllowed()) { + // If the system settings are customized by either the user or + // the mouse utility, we shouldn't allow to override the system scroll + // speed setting. + aWheelEvent.mAllowToOverrideSystemScrollSpeed = false; + } else { + // For suppressing too fast scroll, we should ensure that the maximum + // overridden delta value should be less than overridden scroll speed + // with default scroll amount. + double defaultScrollAmount = + mIsVertical ? SystemSettings::DefaultScrollLines() : + SystemSettings::DefaultScrollChars(); + double maxDelta = + WidgetWheelEvent::ComputeOverriddenDelta(defaultScrollAmount, + mIsVertical); + if (maxDelta != defaultScrollAmount) { + double overriddenDelta = + WidgetWheelEvent::ComputeOverriddenDelta(Abs(delta), mIsVertical); + if (overriddenDelta > maxDelta) { + // Suppress to fast scroll since overriding system scroll speed with + // current delta value causes too big delta value. + aWheelEvent.mAllowToOverrideSystemScrollSpeed = false; + } + } + } MOZ_LOG(gMouseScrollLog, LogLevel::Info, ("MouseScroll::LastEventInfo::InitWheelEvent: aWidget=%p, " @@ -930,7 +957,7 @@ MouseScrollHandler::SystemSettings::InitScrollLines() MOZ_LOG(gMouseScrollLog, LogLevel::Info, ("MouseScroll::SystemSettings::InitScrollLines(): ::SystemParametersInfo(" "SPI_GETWHEELSCROLLLINES) failed")); - mScrollLines = 3; + mScrollLines = DefaultScrollLines(); } if (mScrollLines > WHEEL_DELTA) { @@ -972,6 +999,7 @@ MouseScrollHandler::SystemSettings::InitScrollChars() IsVistaOrLater() ? "this is unexpected on Vista or later" : "but on XP or earlier, this is not a problem")); + // XXX Should we use DefaultScrollChars()? mScrollChars = 1; } @@ -1055,11 +1083,8 @@ MouseScrollHandler::SystemSettings::TrustedScrollSettingsDriver() bool MouseScrollHandler::SystemSettings::IsOverridingSystemScrollSpeedAllowed() { - // The default vertical and horizontal scrolling speed is 3, this is defined - // on the document of SystemParametersInfo in MSDN. - const uint32_t kSystemDefaultScrollingSpeed = 3; - return mScrollLines == kSystemDefaultScrollingSpeed && - (!IsVistaOrLater() || mScrollChars == kSystemDefaultScrollingSpeed); + return mScrollLines == DefaultScrollLines() && + (!IsVistaOrLater() || mScrollChars == DefaultScrollChars()); } /****************************************************************************** diff --git a/widget/windows/WinMouseScrollHandler.h b/widget/windows/WinMouseScrollHandler.h index 506bb6ada40..7851eb9704a 100644 --- a/widget/windows/WinMouseScrollHandler.h +++ b/widget/windows/WinMouseScrollHandler.h @@ -300,6 +300,11 @@ private: (uint32_t(mScrollChars) == WHEEL_PAGESCROLL); } + // The default vertical and horizontal scrolling speed is 3, this is defined + // on the document of SystemParametersInfo in MSDN. + static int32_t DefaultScrollLines() { return 3; } + static int32_t DefaultScrollChars() { return 3; } + private: bool mInitialized; // The result of SystemParametersInfo() may not be reliable since it may diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 5ff592e66a3..dec5fcb2dc8 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -3715,48 +3715,6 @@ nsWindow::OnDefaultButtonLoaded(const LayoutDeviceIntRect& aButtonRect) return NS_OK; } -#if 0 -NS_IMETHODIMP -nsWindow::OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, - double aOriginalDeltaY, - double& aOverriddenDeltaX, - double& aOverriddenDeltaY) -{ - // The default vertical and horizontal scrolling speed is 3, this is defined - // on the document of SystemParametersInfo in MSDN. - const uint32_t kSystemDefaultScrollingSpeed = 3; - - // Limit the overridden delta value from the system settings. The mouse - // driver might accelerate the scrolling speed already. If so, we shouldn't - // override the scrolling speed for preventing the unexpected high speed - // scrolling. - double absDeltaLimitX, absDeltaLimitY; - rv = - nsBaseWidget::OverrideSystemMouseScrollSpeed(kSystemDefaultScrollingSpeed, - kSystemDefaultScrollingSpeed, - absDeltaLimitX, - absDeltaLimitY); - NS_ENSURE_SUCCESS(rv, rv); - - // If the given delta is larger than our computed limitation value, the delta - // was accelerated by the mouse driver. So, we should do nothing here. - if (absDeltaLimitX <= absOriginDeltaX || absDeltaLimitY <= absOriginDeltaY) { - return NS_OK; - } - - aOverriddenDeltaX = std::min(absComputedOverriddenDeltaX, absDeltaLimitX); - aOverriddenDeltaY = std::min(absComputedOverriddenDeltaY, absDeltaLimitY); - - if (aOriginalDeltaX < 0) { - aOverriddenDeltaX *= -1; - } - if (aOriginalDeltaY < 0) { - aOverriddenDeltaY *= -1; - } - return NS_OK; -} -#endif - already_AddRefed nsWindow::StartRemoteDrawing() { From e123f12119cd54c8171672ce98d6412a9b9f1793 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 27 Jan 2016 15:09:13 +0900 Subject: [PATCH 011/218] Bug 1153156 part.4 Make APZC system scroll speed overriding aware r=mstange --- gfx/layers/apz/src/APZCTreeManager.cpp | 3 +- gfx/layers/apz/src/AsyncPanZoomController.cpp | 16 +++------ gfx/layers/apz/test/gtest/TestHitTesting.cpp | 2 +- gfx/layers/apz/test/gtest/TestTreeManager.cpp | 2 +- gfx/thebes/gfxPrefs.h | 4 --- widget/InputData.cpp | 33 +++++++++++-------- widget/InputData.h | 33 ++++++++++--------- widget/cocoa/nsChildView.mm | 6 ++-- 8 files changed, 51 insertions(+), 48 deletions(-) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 69f6e973064..81ec7c33b56 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -1062,7 +1062,8 @@ APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent, scrollMode, ScrollWheelInput::DeltaTypeForDeltaMode(aEvent.deltaMode), origin, - aEvent.deltaX, aEvent.deltaY); + aEvent.deltaX, aEvent.deltaY, + aEvent.mAllowToOverrideSystemScrollSpeed); // We add the user multiplier as a separate field, rather than premultiplying // it, because if the input is converted back to a WidgetWheelEvent, then diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index c616301e608..f6054616b8a 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -31,6 +31,7 @@ #include "mozilla/BasicEvents.h" // for Modifiers, MODIFIER_* #include "mozilla/ClearOnShutdown.h" // for ClearOnShutdown #include "mozilla/EventForwards.h" // for nsEventStatus_* +#include "mozilla/MouseEvents.h" // for WidgetWheelEvent #include "mozilla/Preferences.h" // for Preferences #include "mozilla/ReentrantMonitor.h" // for ReentrantMonitorAutoEnter, etc #include "mozilla/StaticPtr.h" // for StaticAutoPtr @@ -1639,17 +1640,10 @@ AsyncPanZoomController::GetScrollWheelDelta(const ScrollWheelInput& aEvent) cons if (isRootContent && gfxPrefs::MouseWheelHasRootScrollDeltaOverride() && !aEvent.IsCustomizedByUserPrefs() && - aEvent.mDeltaType == ScrollWheelInput::SCROLLDELTA_LINE) - { - // Only apply delta multipliers if we're increasing the delta. - double hfactor = double(gfxPrefs::MouseWheelRootHScrollDeltaFactor()) / 100; - double vfactor = double(gfxPrefs::MouseWheelRootVScrollDeltaFactor()) / 100; - if (vfactor > 1.0) { - delta.x *= hfactor; - } - if (hfactor > 1.0) { - delta.y *= vfactor; - } + aEvent.mDeltaType == ScrollWheelInput::SCROLLDELTA_LINE && + aEvent.mAllowToOverrideSystemScrollSpeed) { + delta.x = WidgetWheelEvent::ComputeOverriddenDelta(delta.x, false); + delta.y = WidgetWheelEvent::ComputeOverriddenDelta(delta.y, true); } // If this is a line scroll, and this event was part of a scroll series, then diff --git a/gfx/layers/apz/test/gtest/TestHitTesting.cpp b/gfx/layers/apz/test/gtest/TestHitTesting.cpp index ee9ccce16eb..6232d9b0f49 100644 --- a/gfx/layers/apz/test/gtest/TestHitTesting.cpp +++ b/gfx/layers/apz/test/gtest/TestHitTesting.cpp @@ -435,7 +435,7 @@ TEST_F(APZHitTestingTester, TestRepaintFlushOnWheelEvents) { for (int i = 0; i < 3; i++) { ScrollWheelInput swi(MillisecondsSinceStartup(mcc->Time()), mcc->Time(), 0, ScrollWheelInput::SCROLLMODE_INSTANT, ScrollWheelInput::SCROLLDELTA_PIXEL, - origin, 0, 10); + origin, 0, 10, false); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, manager->ReceiveInputEvent(swi, nullptr, nullptr)); EXPECT_EQ(origin, swi.mOrigin); diff --git a/gfx/layers/apz/test/gtest/TestTreeManager.cpp b/gfx/layers/apz/test/gtest/TestTreeManager.cpp index d44dcc3564c..11fa91c0323 100644 --- a/gfx/layers/apz/test/gtest/TestTreeManager.cpp +++ b/gfx/layers/apz/test/gtest/TestTreeManager.cpp @@ -104,7 +104,7 @@ TEST_F(APZCTreeManagerTester, Bug1198900) { ScreenPoint origin(100, 50); ScrollWheelInput swi(MillisecondsSinceStartup(mcc->Time()), mcc->Time(), 0, ScrollWheelInput::SCROLLMODE_INSTANT, ScrollWheelInput::SCROLLDELTA_PIXEL, - origin, 0, 10); + origin, 0, 10, false); uint64_t blockId; manager->ReceiveInputEvent(swi, nullptr, &blockId); manager->ContentReceivedInputBlock(blockId, /* preventDefault= */ true); diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index e27a4b7db4e..82963d9e52d 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -397,10 +397,6 @@ private: // This affects whether events will be routed through APZ or not. DECL_GFX_PREF(Live, "mousewheel.system_scroll_override_on_root_content.enabled", MouseWheelHasRootScrollDeltaOverride, bool, false); - DECL_GFX_PREF(Live, "mousewheel.system_scroll_override_on_root_content.horizontal.factor", - MouseWheelRootHScrollDeltaFactor, int32_t, 100); - DECL_GFX_PREF(Live, "mousewheel.system_scroll_override_on_root_content.vertical.factor", - MouseWheelRootVScrollDeltaFactor, int32_t, 100); DECL_GFX_PREF(Live, "mousewheel.transaction.ignoremovedelay",MouseWheelIgnoreMoveDelayMs, int32_t, (int32_t)100); DECL_GFX_PREF(Live, "mousewheel.transaction.timeout", MouseWheelTransactionTimeoutMs, int32_t, (int32_t)1500); diff --git a/widget/InputData.cpp b/widget/InputData.cpp index 273c796c77c..c2edb9ab434 100644 --- a/widget/InputData.cpp +++ b/widget/InputData.cpp @@ -370,19 +370,24 @@ DeltaModeForDeltaType(ScrollWheelInput::ScrollDeltaType aDeltaType) } } -ScrollWheelInput::ScrollWheelInput(const WidgetWheelEvent& aWheelEvent) : - InputData(SCROLLWHEEL_INPUT, aWheelEvent.time, aWheelEvent.timeStamp, aWheelEvent.modifiers), - mDeltaType(DeltaTypeForDeltaMode(aWheelEvent.deltaMode)), - mScrollMode(SCROLLMODE_INSTANT), - mHandledByAPZ(aWheelEvent.mFlags.mHandledByAPZ), - mDeltaX(aWheelEvent.deltaX), - mDeltaY(aWheelEvent.deltaY), - mLineOrPageDeltaX(aWheelEvent.lineOrPageDeltaX), - mLineOrPageDeltaY(aWheelEvent.lineOrPageDeltaY), - mUserDeltaMultiplierX(1.0), - mUserDeltaMultiplierY(1.0), - mMayHaveMomentum(aWheelEvent.mayHaveMomentum), - mIsMomentum(aWheelEvent.isMomentum) +ScrollWheelInput::ScrollWheelInput(const WidgetWheelEvent& aWheelEvent) + : InputData(SCROLLWHEEL_INPUT, + aWheelEvent.time, + aWheelEvent.timeStamp, + aWheelEvent.modifiers) + , mDeltaType(DeltaTypeForDeltaMode(aWheelEvent.deltaMode)) + , mScrollMode(SCROLLMODE_INSTANT) + , mHandledByAPZ(aWheelEvent.mFlags.mHandledByAPZ) + , mDeltaX(aWheelEvent.deltaX) + , mDeltaY(aWheelEvent.deltaY) + , mLineOrPageDeltaX(aWheelEvent.lineOrPageDeltaX) + , mLineOrPageDeltaY(aWheelEvent.lineOrPageDeltaY) + , mUserDeltaMultiplierX(1.0) + , mUserDeltaMultiplierY(1.0) + , mMayHaveMomentum(aWheelEvent.mayHaveMomentum) + , mIsMomentum(aWheelEvent.isMomentum) + , mAllowToOverrideSystemScrollSpeed( + aWheelEvent.mAllowToOverrideSystemScrollSpeed) { mOrigin = ScreenPoint(ViewAs(aWheelEvent.refPoint, @@ -407,6 +412,8 @@ ScrollWheelInput::ToWidgetWheelEvent(nsIWidget* aWidget) const wheelEvent.deltaY = mDeltaY; wheelEvent.lineOrPageDeltaX = mLineOrPageDeltaX; wheelEvent.lineOrPageDeltaY = mLineOrPageDeltaY; + wheelEvent.mAllowToOverrideSystemScrollSpeed = + mAllowToOverrideSystemScrollSpeed; wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ; return wheelEvent; } diff --git a/widget/InputData.h b/widget/InputData.h index a6191bd764a..bbc838a8f49 100644 --- a/widget/InputData.h +++ b/widget/InputData.h @@ -572,21 +572,23 @@ public: ScrollDeltaType aDeltaType, const ScreenPoint& aOrigin, double aDeltaX, - double aDeltaY) - : InputData(SCROLLWHEEL_INPUT, aTime, aTimeStamp, aModifiers), - mDeltaType(aDeltaType), - mScrollMode(aScrollMode), - mOrigin(aOrigin), - mHandledByAPZ(false), - mDeltaX(aDeltaX), - mDeltaY(aDeltaY), - mLineOrPageDeltaX(0), - mLineOrPageDeltaY(0), - mScrollSeriesNumber(0), - mUserDeltaMultiplierX(1.0), - mUserDeltaMultiplierY(1.0), - mMayHaveMomentum(false), - mIsMomentum(false) + double aDeltaY, + bool aAllowToOverrideSystemScrollSpeed) + : InputData(SCROLLWHEEL_INPUT, aTime, aTimeStamp, aModifiers) + , mDeltaType(aDeltaType) + , mScrollMode(aScrollMode) + , mOrigin(aOrigin) + , mHandledByAPZ(false) + , mDeltaX(aDeltaX) + , mDeltaY(aDeltaY) + , mLineOrPageDeltaX(0) + , mLineOrPageDeltaY(0) + , mScrollSeriesNumber(0) + , mUserDeltaMultiplierX(1.0) + , mUserDeltaMultiplierY(1.0) + , mMayHaveMomentum(false) + , mIsMomentum(false) + , mAllowToOverrideSystemScrollSpeed(aAllowToOverrideSystemScrollSpeed) {} explicit ScrollWheelInput(const WidgetWheelEvent& aEvent); @@ -631,6 +633,7 @@ public: bool mMayHaveMomentum; bool mIsMomentum; + bool mAllowToOverrideSystemScrollSpeed; }; } // namespace mozilla diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 85d9a26cfa4..0f2545ab59c 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -4975,7 +4975,8 @@ PanGestureTypeForEvent(NSEvent* aEvent) ScrollWheelInput::SCROLLDELTA_PIXEL, position, preciseDelta.x, - preciseDelta.y); + preciseDelta.y, + false); wheelEvent.mLineOrPageDeltaX = lineOrPageDeltaX; wheelEvent.mLineOrPageDeltaY = lineOrPageDeltaY; wheelEvent.mIsMomentum = nsCocoaUtils::IsMomentumScrollEvent(theEvent); @@ -4990,7 +4991,8 @@ PanGestureTypeForEvent(NSEvent* aEvent) ScrollWheelInput::SCROLLDELTA_LINE, position, lineOrPageDeltaX, - lineOrPageDeltaY); + lineOrPageDeltaY, + false); wheelEvent.mLineOrPageDeltaX = lineOrPageDeltaX; wheelEvent.mLineOrPageDeltaY = lineOrPageDeltaY; mGeckoChild->DispatchAPZWheelInputEvent(wheelEvent, false); From 68ad96ea38b35c11bd881bb047be600a7c79333c Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 27 Jan 2016 17:15:49 +1100 Subject: [PATCH 012/218] Bug 1229437 followup - Fix sign-compare error in RubyColumn::Iterator on CLOSED TREE. --- layout/generic/RubyUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/generic/RubyUtils.cpp b/layout/generic/RubyUtils.cpp index f3b09f6fb2f..80cd07781db 100644 --- a/layout/generic/RubyUtils.cpp +++ b/layout/generic/RubyUtils.cpp @@ -78,7 +78,7 @@ RubyColumn::Iterator::SkipUntilExistingFrame() ++mIndex; } } - auto numTextFrames = mColumn.mTextFrames.Length(); + int32_t numTextFrames = mColumn.mTextFrames.Length(); for (; mIndex < numTextFrames; ++mIndex) { if (mColumn.mTextFrames[mIndex]) { break; From b53c2adb190992d8894dc5bc650d6fae329b6e62 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 27 Jan 2016 17:30:04 +1100 Subject: [PATCH 013/218] Bug 1229437 followup 2 - Fix another sign-compare error in RubyColumn::Iterator on CLOSED TREE. --- layout/generic/RubyUtils.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/layout/generic/RubyUtils.h b/layout/generic/RubyUtils.h index 219f91e1979..1497c93c406 100644 --- a/layout/generic/RubyUtils.h +++ b/layout/generic/RubyUtils.h @@ -163,7 +163,8 @@ struct MOZ_STACK_CLASS RubyColumn , mIndex(aIndex) { MOZ_ASSERT(aIndex == -1 || - (aIndex >= 0 && aIndex <= aColumn.mTextFrames.Length())); + (aIndex >= 0 && + aIndex <= int32_t(aColumn.mTextFrames.Length()))); SkipUntilExistingFrame(); } friend struct RubyColumn; // for the constructor From 7c120d71571c1807dcc5b730937cceedf67a2a9d Mon Sep 17 00:00:00 2001 From: Morris Tseng Date: Wed, 27 Jan 2016 14:12:52 +0800 Subject: [PATCH 014/218] Bug 1241777 - TexCompareFunc should be stored in ascending order. r=jgilbert --- dom/canvas/WebGLStrongTypes.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dom/canvas/WebGLStrongTypes.h b/dom/canvas/WebGLStrongTypes.h index f26c9fba866..039673a99eb 100644 --- a/dom/canvas/WebGLStrongTypes.h +++ b/dom/canvas/WebGLStrongTypes.h @@ -275,14 +275,14 @@ STRONG_GLENUM_BEGIN(TexCompareMode) STRONG_GLENUM_END(TexCompareMode) STRONG_GLENUM_BEGIN(TexCompareFunc) - STRONG_GLENUM_VALUE(LEQUAL), - STRONG_GLENUM_VALUE(GEQUAL), - STRONG_GLENUM_VALUE(LESS), - STRONG_GLENUM_VALUE(GREATER), - STRONG_GLENUM_VALUE(EQUAL), - STRONG_GLENUM_VALUE(NOTEQUAL), - STRONG_GLENUM_VALUE(ALWAYS), STRONG_GLENUM_VALUE(NEVER), + STRONG_GLENUM_VALUE(LESS), + STRONG_GLENUM_VALUE(EQUAL), + STRONG_GLENUM_VALUE(LEQUAL), + STRONG_GLENUM_VALUE(GREATER), + STRONG_GLENUM_VALUE(NOTEQUAL), + STRONG_GLENUM_VALUE(GEQUAL), + STRONG_GLENUM_VALUE(ALWAYS), STRONG_GLENUM_END(TexCompareFunc) STRONG_GLENUM_BEGIN(TexFormat) From fc6fad027c03b8025cd5f67e70c82790540ab897 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 27 Jan 2016 19:04:57 +1100 Subject: [PATCH 015/218] Bug 1229437 followup 3 - Fix a mistake in RubyColumn::Iterator::SkipUntilExistingFrame(). a=me --- layout/generic/RubyUtils.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/layout/generic/RubyUtils.cpp b/layout/generic/RubyUtils.cpp index 80cd07781db..68309fab5d9 100644 --- a/layout/generic/RubyUtils.cpp +++ b/layout/generic/RubyUtils.cpp @@ -74,9 +74,10 @@ void RubyColumn::Iterator::SkipUntilExistingFrame() { if (mIndex == -1) { - if (!mColumn.mBaseFrame) { - ++mIndex; + if (mColumn.mBaseFrame) { + return; } + ++mIndex; } int32_t numTextFrames = mColumn.mTextFrames.Length(); for (; mIndex < numTextFrames; ++mIndex) { From f1a4f2e5188b932ef0dd04c8a05a8ff319f42ed3 Mon Sep 17 00:00:00 2001 From: John Daggett Date: Wed, 27 Jan 2016 17:21:31 +0900 Subject: [PATCH 016/218] Bug 1243226 - relax the limit on fontconfig generics. r=heycam, a=me --- gfx/thebes/gfxFcPlatformFontList.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp index 168ce7d8d6e..e0b63ce38d2 100644 --- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -1554,10 +1554,8 @@ gfxFcPlatformFontList::FindGenericFamilies(const nsAString& aGeneric, bool foundLang = !fcLang.IsEmpty() && PatternHasLang(font, ToFcChar8Ptr(fcLang.get())); foundFontWithLang = foundFontWithLang || foundLang; - // stop at the first family for which the lang matches (or - // when there is no lang) - if (fcLang.IsEmpty() || - prefFonts->Length() >= limit || foundLang) { + // check to see if the list is full + if (prefFonts->Length() >= limit) { break; } } From 9036e0263114f202c69597759cbc5d5e4d31bea2 Mon Sep 17 00:00:00 2001 From: Sotaro Ikeda Date: Wed, 27 Jan 2016 00:32:03 -0800 Subject: [PATCH 017/218] Bug 1238602 - Update ParamTraits::Read() r=nical --- gfx/layers/ipc/GonkNativeHandleUtils.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/gfx/layers/ipc/GonkNativeHandleUtils.cpp b/gfx/layers/ipc/GonkNativeHandleUtils.cpp index 929fb0bb0b2..04e057ef6d2 100644 --- a/gfx/layers/ipc/GonkNativeHandleUtils.cpp +++ b/gfx/layers/ipc/GonkNativeHandleUtils.cpp @@ -21,8 +21,9 @@ ParamTraits::Write(Message* aMsg, RefPtr nhObj = handle.GetAndResetNhObj(); native_handle_t* nativeHandle = nhObj->GetAndResetNativeHandle(); - aMsg->WriteSize(nativeHandle->numInts); - aMsg->WriteBytes((nativeHandle->data + nativeHandle->numFds), sizeof(int) * nativeHandle->numInts); + size_t nbytes = nativeHandle->numInts * sizeof(int); + aMsg->WriteSize(nbytes); + aMsg->WriteBytes((nativeHandle->data + nativeHandle->numFds), nbytes); for (size_t i = 0; i < static_cast(nativeHandle->numFds); ++i) { aMsg->WriteFileDescriptor(base::FileDescriptor(nativeHandle->data[i], true)); @@ -33,19 +34,26 @@ bool ParamTraits::Read(const Message* aMsg, void** aIter, paramType* aResult) { - size_t numInts; - if (!aMsg->ReadSize(aIter, &numInts)) { + size_t nbytes; + const char* data; + if (!aMsg->ReadSize(aIter, &nbytes) || + !aMsg->ReadBytes(aIter, &data, nbytes)) { return false; } - numInts /= sizeof(int); + + if (nbytes % sizeof(int) != 0) { + return false; + } + + size_t numInts = nbytes / sizeof(int); size_t numFds = aMsg->num_fds(); native_handle* nativeHandle = native_handle_create(numFds, numInts); - - const char* data = reinterpret_cast(nativeHandle->data + nativeHandle->numFds); - if (!aMsg->ReadBytes(aIter, &data, numInts * sizeof(int))) { + if (!nativeHandle) { return false; } + memcpy(nativeHandle->data + nativeHandle->numFds, data, nbytes); + for (size_t i = 0; i < static_cast(nativeHandle->numFds); ++i) { base::FileDescriptor fd; if (!aMsg->ReadFileDescriptor(aIter, &fd)) { From d8820757cacf92695ec3863d82d4c2e1e91c5073 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 25 Jan 2016 15:50:28 +0800 Subject: [PATCH 018/218] Bug 1121468 - Use auto* to explicit declare 'self' as a pointer. r=roc Both 'auto' and 'auto*' do not change the type inference. However, auto* make 'self' only accept a pointer which is our intent here. --- layout/base/AccessibleCaretEventHub.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/base/AccessibleCaretEventHub.cpp b/layout/base/AccessibleCaretEventHub.cpp index 4e46391e2b1..07dae3f242f 100644 --- a/layout/base/AccessibleCaretEventHub.cpp +++ b/layout/base/AccessibleCaretEventHub.cpp @@ -630,7 +630,7 @@ AccessibleCaretEventHub::CancelLongTapInjector() AccessibleCaretEventHub::FireLongTap(nsITimer* aTimer, void* aAccessibleCaretEventHub) { - auto self = static_cast(aAccessibleCaretEventHub); + auto* self = static_cast(aAccessibleCaretEventHub); self->mState->OnLongTap(self, self->mPressPoint); } @@ -716,7 +716,7 @@ AccessibleCaretEventHub::CancelScrollEndInjector() AccessibleCaretEventHub::FireScrollEnd(nsITimer* aTimer, void* aAccessibleCaretEventHub) { - auto self = static_cast(aAccessibleCaretEventHub); + auto* self = static_cast(aAccessibleCaretEventHub); self->mState->OnScrollEnd(self); } From 5ba406e8dd2fcb7d2e123871675ce67b9abf38dc Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 25 Jan 2016 15:50:28 +0800 Subject: [PATCH 019/218] Bug 1121468 - Show carets when long-pressing on selection highlight. r=roc The blur event will hide the carets and produces a standalone selection highlight without carets. When a user long-pressing on the highlight, we should show carets for the original selection highlight instead of select a new word. The helper UpdateCaretsWithHapticFeedback() should only be needed when long-pressing. It should suffice to live within SelectWordOrShortcut() instead of being a member function. --- layout/base/AccessibleCaretManager.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/layout/base/AccessibleCaretManager.cpp b/layout/base/AccessibleCaretManager.cpp index 88420283d04..faa1c09fe7f 100644 --- a/layout/base/AccessibleCaretManager.cpp +++ b/layout/base/AccessibleCaretManager.cpp @@ -456,6 +456,11 @@ AccessibleCaretManager::TapCaret(const nsPoint& aPoint) nsresult AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint) { + auto UpdateCaretsWithHapticFeedback = [this] { + UpdateCarets(); + ProvideHapticFeedback(); + }; + if (!mPresShell) { return NS_ERROR_UNEXPECTED; } @@ -488,8 +493,7 @@ AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint) ChangeFocusToOrClearOldFocus(focusableFrame); // We need to update carets to get correct information before dispatching // CaretStateChangedEvent. - UpdateCarets(); - ProvideHapticFeedback(); + UpdateCaretsWithHapticFeedback(); DispatchCaretStateChangedEvent(CaretChangedReason::Longpressonemptycontent); return NS_OK; } @@ -514,13 +518,22 @@ AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint) // ptFrame is selectable. Now change the focus. ChangeFocusToOrClearOldFocus(focusableFrame); + if (GetCaretMode() == CaretMode::Selection && + !mFirstCaret->IsLogicallyVisible() && !mSecondCaret->IsLogicallyVisible()) { + // We have a selection while both carets have Appearance::None because of + // previous operations like blur event. Just update carets on the selection + // without selecting a new word. + AC_LOG("%s: UpdateCarets() for current selection", __FUNCTION__); + UpdateCaretsWithHapticFeedback(); + return NS_OK; + } + // Then try select a word under point. nsPoint ptInFrame = aPoint; nsLayoutUtils::TransformPoint(rootFrame, ptFrame, ptInFrame); nsresult rv = SelectWord(ptFrame, ptInFrame); - UpdateCarets(); - ProvideHapticFeedback(); + UpdateCaretsWithHapticFeedback(); return rv; } From 3eff303dcadeae15b1e5049eac43f9309f19bbfb Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 25 Jan 2016 15:50:28 +0800 Subject: [PATCH 020/218] Bug 1121468 - Go to NoActionState after receiving release on LongTapState. r=roc This makes the state change match the user action. No functionality changes is expected. --- layout/base/AccessibleCaretEventHub.cpp | 9 ++++++++- .../doc/AccessibleCaretEventHubStates.dot | 2 +- .../doc/AccessibleCaretEventHubStates.png | Bin 92942 -> 96109 bytes .../gtest/TestAccessibleCaretEventHub.cpp | 5 +++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/layout/base/AccessibleCaretEventHub.cpp b/layout/base/AccessibleCaretEventHub.cpp index 07dae3f242f..6be65aae7fc 100644 --- a/layout/base/AccessibleCaretEventHub.cpp +++ b/layout/base/AccessibleCaretEventHub.cpp @@ -327,9 +327,16 @@ public: rv = nsEventStatus_eConsumeNoDefault; } + return rv; + } + + virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override + { aContext->SetState(aContext->NoActionState()); - return rv; + // Do not consume the release since the press is not consumed in + // PressNoCaretState either. + return nsEventStatus_eIgnore; } virtual void OnReflow(AccessibleCaretEventHub* aContext) override diff --git a/layout/base/doc/AccessibleCaretEventHubStates.dot b/layout/base/doc/AccessibleCaretEventHubStates.dot index 0a440d1644f..bdbbf60619c 100644 --- a/layout/base/doc/AccessibleCaretEventHubStates.dot +++ b/layout/base/doc/AccessibleCaretEventHubStates.dot @@ -24,7 +24,7 @@ digraph event_hub_states { PressNoCaret -> Scroll [label="Scroll start", constraint=false]; LongTap [color="#E8C516"] - LongTap -> NoAction; + LongTap -> NoAction [label="Release"]; Scroll [color="#FF9022"] Scroll -> PostScroll [label="Scroll end"]; diff --git a/layout/base/doc/AccessibleCaretEventHubStates.png b/layout/base/doc/AccessibleCaretEventHubStates.png index cb1f63b25f2f702ecc3e9eeac337fda9e32685d6..4d7cbd81e7907fb3b035f02233657d1c3bdf7ab3 100644 GIT binary patch literal 96109 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Ν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

;OlDsS!H3uxrH)z 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%0DTJw#o|D#T*i1Ozf zkURsc{kr>N?YHQn%3`S+1$w!>SIRbf0vVsenCM=0n3Fw6K{|U%2zbqm&K#hHk?0u| zysC^{%YsX0y2ohuyU{8=@c~IPdl31DIlx<_+V$k)b1%(j>5rZc%0~k!!n^H%*B34kTu$4XYT#13 zPe>2YRKKe@sGvBa)_=TG8#w3=LB(#5{L?%Qdub0ff#DwH02Iam{xD#WPn{ZZO-sPX z70x#f_oV@KaCV$&zZ1zhdNGQrqpNX;W@Y$U??p5`m|Ah*RqYF|}y0XqgD z_3FhP^0VWZD}`W@YXCf!n-FjKxyt!W`f1ty8Qc2f-P;%{aK^= zE91%O<_I+ndG{ccs1BE$KPmyaO}qaK+LijU+bojZ^%C%8OHoYFI^d|v3pCH@wS~&_ zL!K8X$o2)@031C}VYrT*P;Hh=B@&$IJxGgR2%S3|pVd*?%F1f;S+DVz34z3v6ncO) zZ8Bq7^jz}CBz_ilu?j@L2uR*y8M|P5NiRD75npCwBrDOa&<@G8Xt>gByad+=VIXX6 zZ6gFm#CD%{X?IyL5D%ja;6?q&yXsu(DA%^2#_>!(>&*-V)oa}46BOgN=$Dtm!njxe zy*+J2qhXT`Z5ZPF`dIWdOv^S1$+ZDDKIUZxY8&TQYi^S2;*n+Iokj3sy z1+UlfvPGM5Ewws|Z%wfG=_cy=`PW~W-*A$(QR?T+1bYWO2@O%|ua5&`rHq9#i40#K z+Su7Z9bmX0mN7hm2XXS6_eaf4#8+7w*>&^GU~M()Zvl`6PUIP&NJ}Hq5T6ug`o!Q- z@YQiaP^TV<6Qv;fhDpQ($3Fn}zZ0n%5U?OH=qNhq%(okL8weN(3H@x$HA<=M7|d##zx&{Q(kJ ze;lv$srjG<*5`85ejv;zhhp>q3JctKnCY%XSdIgOZ$(p-Dps_k;^@!Bmn%gQkGhr7B3T#D^j6#hI84w4J?L zXm)(lZKS=$e@8?ec=zuFknN}p##6=FhtE`WR8>sF-r~xE%Uxa|VVPDeYghxK2z0fURW|^DR*`gL9I9mz9<^*K&==UDFb#MQ|k<78SiGNqiA+Nrr1)hsH zbp9=TiRL-;zZ#@Fo2U3JCX8TI&9!g+g({Kse*sQYPtf5v^i`D}ZmuwDLI7}ntvvFa z{2DN;H!Up7=X@=L&0$|+V{x9+MUD6!swi93S#i6$i)du|jeuJ%$p(}@50rn3VOG}M zW*|diz{l)leb^OH6qYt|8g1yjK_STWD|+F_{1?zlAoFbiSKUj;gSL5+XtWo4)izdZ zH5Fz_z;WjPADYfOD$4H*_cIJ3F-WHfA|aha2m*dZr9q?{>28o7Kv7BQp;77X?vfag zl9rHeq?>#A-FyFaEnyb(zUS<{pJ#s_L%0@i_y+>ZRHk@rqwGZ&g5Y=jvyxK!-!&rW zB_+!2r60u#J$t5qM@rZjFVf|{XK*ipt5Tjx?8N{(iOLQzC`N%hOAcIWVdurqR>zfK zdEcRo2#jp3!^0$YFUR9BJs8BAcP!;Y4zy5n|4rzgI{5r~g#n+Th**jya+U&ezg~i6WknF`R5=XnP5b~3+x?=Fm57_rIMgev!7R>!kT@hft4(A@J zLV-q6h<&$g3N0r>>lpm^}?fBVC@%ebJ$J{<}ty>8~6%L<2 z4IC^j*uV+M;|ZSg<%516%Jv@CnAU|h$^~%tN9XByt0%;9X!e0S5g+*4|&o13a(y-6wh#stg zW0`OdGojCl0T-cSBn8*k^IVBr{c#Kq*hCq6*<5_e$RWFDa zKOTF_!gvTa)h(+3(XV$}F(e`&VsIg65d0inmsD)eHv%zl7n$)u>X_nX-|mA?M?+r~ zmAauS250(&eS)Xbkxs*c1*#Ojh+chI?1TF+8z;VNmA&iE6AAMFU->mWe0TLLmQpjm zoAWsw815A$bOFa?=pBZo+sXR@MTtsi=K|@dL7>w9Gi8kcr`E$%YmBcwO}^k^Hl1tq z?DjkYXNXOpa%K{@p6}ZiFtBf&vw+iot_&7R=t6b=`u_^Ics$CvE4VK9w`CMu4(!%O zCEi0ml@}*F90N%RfsAP&BD{SQSv>f$5PJ2LnC1_-*+->Z1$j+-h)kN5i7=kN>ID!J z9C1KE&@0#AEA%qPI0s)c?WcCIFAU#G0Xvo%)gXIKn(M|Op+PZOh~ILEp+mzPtZOM6 z<$<8(9k*s~SWdwE5lDup$=5qZL0ZU4U$ha8<#c793qJAUvmo+m;43@_%kYfiqs$&O zGKBDLL`E%ZETa+H~%LY58 z7Wn%E(}~*aR4iQFZElD z(o?oNj)nsFJN^KtVe{n}se#Q8J?W8>H?`mT=K!xK*v~Gqu4+`OQc$JD;2Ee{ zDXG#ynI%X4Y{8X^0+ykgkJ~zOclVI~1MoPRFPj33336{FI_mNO zqgvn>^o^A9$*f}s{J(vSRt@lYf60ZWd>3=qVVtWwV|V$8M~;?`fsHY?@PHbwP$5Nx z?|}3VwGs@sI3O2hy&fcEjUunK{w;T>wv1Z2*j8cstNtxK1F;I^C`8^iCF`L57Y-#1 z>jiM=Au3AG6y*`Dg8<+|c_ovT#FGc~I|WddOG0HHwaT-9Hp#_m?w`E{X3IWsr7{7} zPqI@d+@#2`#g8B0=UZ9pnv`HpxzN_gEct}KH?Qf)KV`YRloNy#!F@nf`xlLEMjoEx zbgE?0ieHQ^afFK5cRJuYUw z5CuiL!b0HXUW*|Lf@RtQJPwM|dOvqVwX$|U{5ReTiV04H&A1@x#YZ12k2#|~SLJ$c^4diD6ek@Bg)s5%pC)hnF;D1kc*zX9cFu=hp z|5JL?Wt9y}HC>FY3xTZAM>kj|XsfCl3Y*U04O+M)+416xYj1fc$Rl8hiaS>bh7Z7~e>%z%Ox=G-aL!susmklN1rS z^b1(THw{Owze=r8YpjWMF#$dVk&6_(iby@2klH*$Jzp&fc!-q&apTRW8`f0;QpzkA zYuZ#_@S1n+IDV92fVYl4y7wHEH3VW@0U-~MzhgXHkf9upZ{gG`WysS~bZ9=$hDxKx z{AmxaNzPf6hWZ7#o*m}p$AQn97)KsZanVQtP+k*QVgsvvduZCqvKevmJwPoAsj~i((SfkJphx#B>1W6G!G2l1VbSEI?wn zq9{+M^}UVoq4*>U$uHvt&V4k~#@9zL^jwD;H=SGXp2Hw?;~$bO2hKins^`ZpXmnRE zeN-Xv_`)=f3@2-_ohoN4HnYtiuXnQ%So~W!{O*Tgf{l-LhUpu!0&rG$&wf^tFvk>W zdv?(CI19jE%Yi$Z{AJWEf>Z_6Cem)s|Eo9BupI?&KtY(?#*5};Wdx;j?fGu2GxGSU z_1Ke+1xEhmM$bbM3F}$Vd#->jn^?e@K$y|F!*Y!eHZvD!7JQM=&cHp@R{VId93uyA z&}Be~`3hbHoxTJf!~M`&fm9$QK%{is-QDfk{VG~f4*(I&SXIboT;YxliebOZ;!3Lo zBeq1k7lO_OBLjP>Pxg!^SF7y%zkc~6%L~oBTID(HCHQ8#Fus>T3VlIr2FoUu(G2Km zc4&ADm}&^~p*{}?XoVCUQDL~b|C`Dz(8wq&Q~LaR0D>l*yQwWOl~M0rQ++m`3znsQ zr#Qt+im4)R3YGQ(_zg@AnpH3GOTK@D24d&~n@w=ttD!unrS4v!`mzIOa}qQI@YtDl zW@Jpd^$s2gCkdInbvq%fEwfuuc_h7V^Ij_hq36!{Q zjC|1}*E|s!gPhq*;a4{nkN?WV$PbtI|7c4TXBkW;~#xc#i> zzZ=#$Dy0Xt)&S=I_7WX{NeGXO0O!f8yCK(7PS7BYg!qH-8EX!=36v=`6Tp-t-QpIk zcLl#jV()t#0dx@6TQBSiC27dm=fAz^JOn9THs#1-2t(8|Kusc8-k&i)+b-=O$y?{+ zu*rWZ6rRY~(Swr0J}Z3}@JLqr)g&HD9ag-kiPMkCqT<8?hExoC@DCVc?|)hyDuI&J zvBG5|1v}6hB4r0|+3wqHo1DOWwuJy}I1TDr9t2n-b)?{RslC|&wU}dt(Z;F^%Hdcp zL*OA%x}z0&ULQ}ubFp2D%=+Vn>U485upK3~7<)4p!adXpFlw6x1jza)>zw_T=(s7KgH4S2sO6n(NPEP1sbV9m>d zLaItyZl(tqvc~N^s^D*7(r*kJ-cIc&B2(LHiu!O8-P=;3G{L z`Ha5!olcrWQd11kdCVGrkIU{Ha0OfE@F7DnK$u3C`(1mP1V^wvC0wSiedx2_7Tkng z5ZzV?4hVlZ=DS?u>R-zjcPy{;*=u*2C#BeyB}6P34>Bm~XsBa4R9rwyjYlIxB{eV? zCKtyp3n-8Sfh7ne!u+WuIRD#ZeL)wkxb8kdT|pzii-_R)Vv5t>Sw9Y zmTtS_h3Z-Ge%>_7fQk=mKjb&6q-_>qkEM zhRNSrL(x3GKN>*S7_&SE5s-03TMQ(vK&qA-yNWe{>?Z;GUr_-Sm`p`r9S*wWePp!g`+XyrT&qfjz*aROs6>c<(J*8{W4>`VdLONUp^R`M zzgft}sM7-uEcAbTW~<42Ob7%d!`#;pBU?RBwF|Y|fcs(0=ixhj8yq}xy$*LYYghS#%vD(LZw^fO24e_=E<1v;Y>;-o)l_Ds`uI)ah&(4b(8-m2VJUaJO zLMo|?~SKs|9=yZn75!L;;jPLLp+6*96PvT}*iCAsDM`Cu8`n{rnnwKSl(dJYr0>LzPePM7G`dxWQ*tw2%9 zTsj7x;^!t$ai8Gg2exAV!^<^hIR(($zB@9q))bpdh2G1z|G{eaM1aPF#z4JF-vuoJ z?{*bXFp@v-DP%u%?s=5GHvv$ru|x9t8YICqJNyirFYZ4xRS0^kPFXxxHUUA>*hR$j zARt4jQBhGu1h+jlYlA=~EC|SijWzy;>Dm0LuhIqu*wZDwq&A#>@Us+Nqmzh-sDq}r zGM^wyUpQB1^$zZAnXOg3d5(+D2+Iye5cE#fy`0$a3Y$+JXnw_9zETS7?;rUxkmcID zqZ2?!Gp=|@f|wbp(#}N5l#!UTX%yCG8#iR`{R(?Bsn>pPA;GaxUw%_;6#uu& zO}{*!j7R-NNJ63gc$eHpy(!#9>5Vm7f5xh{AOIwF_T2RbprS1gEnHStz?>mifc}2y zxlFv2%x7d2$YmovLJ?v+WVS>S#bx6*?7PA7l7CdX+JW4z(>1lo#xCYaHxvHJf$iJY z2+csLo??{T=KH3`VvgLyrTp-h`8x$$ER4(@hyKA2~C)+@E?FHAr zJ<%{GEi2A@tCP~m+rwXy10UF0`3pY-1K2XRbdn1RE!=i^SG``yVZ*&>Cb7Ory}^Lf z)}n0PUFZ*=n|HRPSx)hkc~QegD%%$Ns1IE)GE-m5{X@}0TffgLp{S7iw)pT|Wy}4A zLlpLanQXSqOS<0D*pZ{V8YT~_wIx014sJu+F>|T?_a2GFo;$Ok9rHwd9YgBO<%jT{ zb}kEQZAtWqqh-6r}+ z(=&Zn4$a1yIx!DBG66`6LGqSO4Ua|62HvV-wp9qMItPmv(rn7KIxb%6Y4Ax?_vg zSMKBWgpjuc-|oeJ_fL=6O8SPuel>x6NRh62f}w6p5{P}m4?9@-@3%u4_O$b=IaLu9 zG(FrX6BL@=#Ld$xV zS~C@cd%jk={sc$JlC7VXp1C8zn{d-ymg@y`YDuoPPG&v#Z`THznfl`Ip&c^^oBh{) zhA_y1g4*t6SqD~AkDFsVjH~i;7M!RjM{t z#&V9z$i+*l$i>=Zx6b&fe&6=1AGeUBcKBZz9l&SOO_g&5_K!bIMkoj#DAtLWlTR8R zgvRO#KDRFsRHE6gd7EAIizrd37stz!{GC*JBc$cjQELWbb%U{F*QOQqQSz)9w}8UY zZhq+{ja#g`s_y@rYsCP0anv{Y>UiyxwzP|H>?$_eRI;uGG+Qm&UPtT3=&<#P#kZ8m z9UvVcp!bsmt)jPng!e3vb7&~=E0PsHg_swRaq1S~Z;^*wI~)iq@^(8vFM%X1Od5cg zX6Jzhd?DTQS2#(jVi-rbHCqy`l8_dXY15ca4DZ+$bLuFsr`;t#Y~rWuTalnXAX0$w z8l3wr;1g6Q#q1+gvcsB<*mY~HgZ_fUzZdbf9GP_5{5Q01(CB1)YE&=E=>`RZ~ZKSz2rYv?v^{K6NTvo}FW+ zL@Ls^MH3IN#sAbib4lCo(PI$h-6fEbnNYECmDh-gCf8v<&x|X+AFoQT%eG!E`5NtX z`pb&p0enG_(j^BJ8#AI=_g@>|SQ({oJ;*tcP7l30jfrR{Ti0|W$`HF}e8p&LbxznZ2e8yfFDO z|FwRUHeTl9DFF)#@dr~alw-Ksm@>KOO|SYvi|=n+*G^CC{xO;5uN=}kx%Uy06+^Y` ze#8{mlJC#d+@kAgTFKIk)Hr3lyy_Q%h>-A%aGAQwEKCGMs{;SJ&6G&X;xMiXp^01D zPc8+M#K%lyCUew4(wYPadb6_>l^$l>9l5pa{~lK>+DhJNuW!6@zx$bG67z%*1Z$KP z@`TK3d%x#sRh2ax8`Qboz9!f)SzwgeZ3>a3LlF(((u%(?U2r76bew^jG=XO0RTeSz zQ`cOzBAwr7_t+X=$$m>c+Q3Uu99psHohvl@Md*fE5OL)aLO#<~I-MmlsX-`;zr=jDPANz5 zg51reo>r^YdiV`TGPX3am)pv5lMbXA^4sEazyA^iwkPm5;LV3Bb54CZU1zWnJK97{ZEIXuQ*Mh%Zs@jvM4i*q z|4<3a>z|SXnHI+yT3!DS2}!vc)vwU6HpThXK1^!W$Uy6rloc^!Zhx?WJ30g#+nIw} zQ|nDwv{BesbL)dgo;REibvN=%R4{#H&(Gof2Nc=LFhZ5k{j_1;2S9Q$Z&Ush4tb3e z7BLC*a8q-ML^v2F*WKyp=HU*J&MWPqv*w}FbLl<@Ulz0yp1XkZ@SXW!mCFoGuM#b* z?r3vN5v`vZMA6$wI!k~PZg|S^Q~FnBmdh5(hQUHO+3xj;bFa>Io@w!omba(qW{{mB zo9;Ck+uI!`Hudv+sTj^B&LXEl&qr4Wk_Q-YNg2>hCe%Kd`*bnTr>6Jz4hpp^!ZzNE ztPJoBgphMAH=WMKfT83s{S@)y7_v^x^YN<~wB z@5f=Z;~^C-ObG5Opl}!JO&Nk(_xgDJcq@z%MYIrv)u!;}3*Lo0#18ay^;4R4&SsHfJ!yFf*?ddN)VrF%1t~Lk=DQPn-txQm?lrou;=2iNvKsf zn^%3I_%by!7~3e17}Y9kO0&=q8vA6?GA+t#FiS}q-uaq`ff!L!fQHzP6WiC=|3S|I zb$!LX-H}WJXdI&%Msf>SQ=4PB1N=Jmu6fkR7`7RZeI0qXBkv5N!Khw7Gd#k1+>#Mi0Iw+0cD4jMwv&o8XblH_UoL@^R zpeiQIHoUlA;<q_6hDb};1lz)4PN3zeD>{-#5a;_jnr8{Y?d2Lo`}}VZAewm9uM^P>-$8<&yCo-1UUiwhy_U1z8krFACQ^x!I(lH zEh_!#9H{sM$RuiIDIpZQ;7I&VH;qw*wkiic1t+hX_ETqyjaxALF}>4j?^Jb&K_*;% zu(~R`>cnNL{Ngdz@XdHYyi(m_L;q)N{K={n4cv?X{U8gpQw15-fR31|_efTj-Z8go zwflVp{FwpA;uW?NYr5wu^C?i=yiqXe*gBj zwjY)NwARq8Y9r#n_dlzm*8YNCONIbmyV^puOR8iS`E>J1g`;Szph6pDf{I9>=Ne>6 zD98eFC>_6iAW?voQl+BH)Ts5pi{T%y`@ygv-R8T|D5j2u0~Jpq$9#NYC7%~+Ly(?a zSeV@+BWAX_a~S#ML4KF|txe)qODwwTv7n4GoXzl*pG|Y^UAW5-uhS+;P&Bu0HF~)( zERk;V&Qrv1-2Q<|Zy>>p;cKYx;@N*6d{-4~OnXT{+#s3^zqow&Mw|45*cT= zy?VhJ+IQN29a)7PmepinnmjmlRh+R(rmv$xEUMvPG|a+F;jHsfn4?FmojhHv65?R&MM;(C9MxPBF+DUNruz(eO(*py8{0A!oe- zyohmkok}As*vH8HXVZ=BPO|zDTUf|>hf)dCeq#QNz=ykGo8P4Q*}KkrkDl#uXOO)? z7*`vQ;Kq=B^#h5SZy9$E73#Z@c}ctUGceW41p5C7aN->{-=(vy)|dWMmtg*n@_Z<$tkM`>SX_C*^p-wBbj1M|6Y%wb?!0dP6 zG;r@rl}f4oi-W_8Q2)v@8#0-g+P@THr;^yCJKBs z3(PXkT?OctFl-86RCOgvSow!G~jEoZY{Peu%>YT6isg=nQ~ zqpMAX?6e(x8u*}{uh~iL48O2BhelT?DY%xq?#@n)MSYTb{YFS`0&^8 zUh3&X_yzUts{wrI7(-@2q}c6)SE)|NzmkG(iZW=t zg`yE~S(pbtEw9kC20n{1P-_1@YFY;35t*uvQRfG$FD5?-qP(6|My;BAf3M41(F>za8)2t?95zk!$ zrHRH}4}j=TGx|t}kPNJlwL1q{2JM9LSLJhJl-tb;0!MXmzTJt@(8^VQxHnkMA{(oI zzEo55mg`^xi}BAVOEQ%#)lB4m_$+OVGK83=$cVBG&JejD9vp`^iOs88ZL8fOF;5Hr z$c|#F^&#Sqi*%~^L)9_;+?yC^=O16)Z~JUNQ5PC3vcaA_wrE+G^m!hRU+7z6+fLo5 zv!$V&>7IDTRl=cd2`55_RHyZ{U~)JCw~I!Jf&N18%6{>JswliO@~#G#JY`gtUHz5r zV9xn33&cS=t<_?U2`=QuvNvmwXKlEeo6v~>fn|RbX~t%+oX)OGmZ_(` zF((5<1)B=TWf4R!kx3y+AlcAux4pSPyp%GpGe~^++qEkG8X7c6=1p+ilAT|?q8Au| ziv`VFOH~~oN;iYOw#dlexNi@{t`=!=M=cz%VkAoT(-tN1S6S^aq{Q2+8YPID)@tqU zrtC(|^WR?JR7{#2CUC}ld%G&5^F>Y-@m_d{#bXOdRWChGvTAtXMOD#wFb3Jw)KOv;DgEqKFPtO(9Z>JRwq)`GJ~ z_Uf$;`t;wfGqkosNm9+(w%}rK* z`xO2pwa*J5NH-k20w+T$tdyr7pS1@xX{d;TI8lWK=p-)61tVVjkt#{+6riuX!`=p- zqWC*I_}8JWil5o{E0w07->j}k2q>HU-FTHAuFvjf!z0U?C|KQus-Xz6Rbvx)^LyXY^}B-(z(b^ew%e+I+Kb`2E*Z z)un%le2V-)5!3yeX`3a&czTzK4Tgj*LjJ&gMYLS4DlL2gg(c}RpFi9) zQGfQJN@Rs88oLpx!x-0)+mH7m{PWNME1^bwqsZ~71CGRQCP+FBuj*%}uB2;sqf(bG z64_+8FSftb_U#f%3Pp+{I5Zlqjn;&!!sKHr6DegrV%OyRBd{mmTgg5&)^Gw-^E#N0 zHTHg2gIR!3HD3*84+{-#I|I4D3~KER|0Wtzk4uQ$`;TLJ7+|t41^yynn|HbPm}0e{ z$-o*4yVn+5p_(P<48+%@1HMuaE}7s0ZTrjebKORL2^W9-{$2*7Avx!j59y$jHc@omXg>_MgS)Is;H?2b$wfVvojF-m|-3SPh)= zqNfk0iD}O-|Az7mb_7>_iRae0Mv5r38~5LUf)$uQ6R3hO00y4%tYDFbz{se6dTZ+N z&r?3ZQdMe2dd~6nsE|gHeP+I0ZILX~B#Yqs#p%LByJshFC~TbFD%#&XZ_hU7C;i5= z!6Xjn{etyk0BXIs(Vr#f0~ZO_Ndd&ho-@aKV4oWZLqPHO|GaCf+@T&d+o>EZfBaU_ z;{ghM8GL*paTNtK&1M@6QzBcczG;=O)1}+JI~ZJnOSP`*?~BNeTi{$y^euh%uOiri z2`#C8=WenB{wmQy#Y}0F_EyZCQ@OO*9P4*5+d7vV3&>FkBGR>88ifI z?yro#4?Tz41}T1uaWw@ZN_WZ6&M%~jv8sJY>RNwK*?xux^tQ3kTN~NOw*=(cqKdE6 zu`IAz!nyHOqyF8u5gdbKi3%7GE;fCp$iS9=Ft5@0f}j*KY19@>qVS^WFM>AE$q%5K zl1`JQq#I8STwJ^#K7VcWU1#(V*dI{y(l=Spp59qtR0E4zT|Z*2F_j6HY9w0iZT*Pd zX|3$6cQTHr$e#W$_4Hf;_xGLe9z3b%P4Ao&{hrLTfpKSEM!?@Zm0r_=rIRD8@|%+4 zKF+?Owu*9sI~U4x*k-tLb^eCMG&(dIFVhUt$2oQ9?fY)j3~He6HjyArMo&gyuZab7 z`aXgPzF)u+@F^2mBHGc*>%%|7MW2L`pz{llHh=d+^uUwR@}(7kk0B-zSdX#B`@kI0 zE*c{mw00xXODjGorn{EixOJ*=o962tz~hlY__a7N70-Z)VnE0Yx=#xzh}66$^x;DPC>wm)sly|iZd5dyO_>Jw*K=2WG7bhGd4l#r>R`59mk9vrhkH8 zvlynoGWUgzXQQjkzj)lXbMX~+oXfe=5}<>$gR=4(CkE;apV&l$6S z2Xy7isejA;W1>fj&Df|Beg&?QS++wir2ilgyOV4~v(Z`I%mZi%(>rpEc?EWT zQWj!W+S(XswQ^^JY~@Xn)@_@JI`%Lkkd-zYJLRUf1f1qaH;A6NxW zELss!FO0trJKaUNglkU$KJhyY)`hq5d25s(Xuc~cYnC0 z8l7`0&2SsuR=mvSo?>?}(CTNxujH9LC*Jvabm(Aq?pCXv*|?`eoSF{#@&h;bT$2*G z@aYy(kgR1STJARzv_5hgaE$%O(H0Ho9D9fsRG>_vY7CKc)6Gp>+fj` z|NZhh@QTW|maTP|6Jfsth4a_&?(h*L!HOo<~x`;)>Q)qNK8% zE)RyKB5YB!}ZO}hWi*SM#-2WVbL(B1O6BtP(<@;Xmn zy$@ZDHR+Sd!s}Y8imd5rPMzra^K08vzvUg%sxp?1z(mAXPPo=r&Uf0hK7t#aAFLlV z8R>`|e<}-{uTs-XQBX!ND0{ z0C}4x5NX|-((%!`QB%)=+tNY&sP!hc0Nj8qH7E!$z ze--t=(Y?i&pkFWWvu0OF)Nj zt)%Y-_tPf0#y`3&dL;N za^DE`+mObTVRq!Zq=RF*pRdB=B}`K98_`59^8IQ7rUbMpI|T-6oODI>K^q;;uGpaX zp#rH2dx{GQ0=}#Kd0&=@&J|eSg-sL#92V}DD}_0cQZKncP7#8FrTPIR;LdBxr`dFu zBmkU{RiFO4gJ3$_CFMBhpZ^W@0yD7f?qdyJgKxKoV27SMfmGpwa?E23jB8l+SZNMG z7Ev!?l#+)RDm)a2-T0PBC5lOLebxBuYB;|6t(?mw*e}3jk0V!S<*#$whD2wxRS=2u zF!f62sXDpox{LbCsys)}Oou?$>D!mECwvXl-?e4ywE90Zo_fX;ob&U@XXVGYOuSsl z(xZ-=)71E?^PACo?2~^2vxPxAiya|5TY8J0BKMYt5}}=XAMeQAmZ7?RU16iCIXPiQ zt&m-gk7Qlxb<#>t_D5f`8m=Vo2RS81-ze}U?e9D+|9(*6K{&_$>sol{n%{i(7oXHL zfRKQW7p<3wAYd!FCF#{7|4rPhQB_mFQBmdmydlKd|r>l9)+CwWWW$<6~( z{f>*gpDY1?Ml+T$yz1XHbHK@z$s6qs)#PXV?Al$rEaHYp?M2Aoc^sVvbRmWO0Blr5 zhFkT^vZk7P(5~iUO;1jNOsu6-$F@MM;1wgWRFpL%@A~^WYDcV?e(nY|WUvxngBMmM zLE8)aci~mJG5fR`!D~=<(c|@GapKd>h(r(xviQ;w#aW>LTrfX{^_M4(W}Lp3OgeoHO^^kZ{|zUhvu9_oBPg-YdbzEo{lf zV0Gq42T@nh>A^qlch8ItapSp%PY>xjcJ4_f9j|<8c^7yp4jj}RDj{1bR?9DwrdlgLHy8BS1B7H?w{9<&mSrsvH z2P*kO*&rh-QnSO0Id+P)_F-FJ)hlS>CH9kRwXONvV!6P)f|l8=g?GM)$KeQhho2D- z%%<#OnK|(Gn%BnN)+l=Qu8nt!4G2&GsQ%0+Rl)C-)21jB;T;w}oo$vlYSfO_{ z&3Czl#pfJaYZ@Ia7nUP585Oi0kFH7QG49Fy(Wp{kG5A7_g7tyLCSa$UbM|%5?KRjlCz3 zc+*V62asoweS87OKmvsQ>?EXDnj||WBvDwP0L6|O4Ni*W=MUOc*C+X?ay5#Q5_f)f zwq4j>fs9&3YS_x+Nmn}dNaakq-Wu$%T4b2VA~D4KVjPxf?e|W2D!%F^wN3iV+waD! zA~$hA!xGoZH2=imUwJAQ4O>cXj1@#;SX0ma;hUPvTexKPFkqsMzoCq|x)!*8``G{K z7k_xGl)1tp59ZewEQ%vHGN{0+=b8V_KS6y+`i$$Y#Cf`u1UY3=V8Tiwz|L&Xhf#8P zKlXm>0HI=WHXiiEs!nKzNPi_7)!#I$gY5@V!a*v}YuS49_)ruO%Ya^uxzSp0wD2Wo31c>OwLS z!czYu>Pl`of>H}MQ-hAB)4nA?yRuBX*9u@dGtIXrn$>|ej5xXeW#4}AujIOCW$ELm zldi|vxc8j44bRL@5YK>ha1i-*R*En1#8uY?%gG%-A#1bH&3NLq3n!fn}n}Q zUQNE6+e&9wV$|hME)lcto}QqI^_OV*H+8aZ7k7ZNL>o5hLyq@r+~04FjI7lDA&7w| zyZ3!A({}C>T``-@EaG>$aj#p%NKv_z7?Qk>=ki~#Q)j1)sZbi~&Iq|*xOKeGlDK~< zl$S>!*1VGQ;H}Q)*sT7zlv(Js1cGBw@0mj1L<6_Ac70g;XzQI!Mq~d3xUH&}WLP1u z_b@Fp-eMa)XX?->(m8)xZDX-w_u+d+F3iRTpaV0*P*IP9SZrgHBZ{Jvw|0K2N2%gD zd#;>z>8|9QCq`$XtGNgIXb%5G->L zXW$QoeRdL`ac6kt2g0P4{HBtYN@+#zkKTKFSqV3%cAZkm4RTurUgVphq2s zeyp<)`N*L@zShZMq4|k0-A17Krl)jr^-6I1j9=^`M9gjXd#0^UmELNQ4m{xhvjFlX zg?thb_8yhn9?Q6%+)>T;Rp^JeRi=f8T)$~|S&wzAN8R4W1UJvMvq|>#`RB-%{bkP7 z7!Ast8fNWXMR1t4CtrVbe&D&m<#}*;Ba%6@avmJ8*x zoKtg6S7=0ytF=Yq>S#8|;&Ns**LM*T{{=02VT!xoobTaRS?=<-(Sm+@tH=rnz$QAn) zQCl(Uy|Huf(mnJ;7EMRu{|q-$Tn2lOm#BM>70usV{bVA3?hcF_?4L=1P}sEmXuJ)$iLJsY05uKlA>REjTNPBIhF;S zmu0k@ysG|vx&SR)BJzcT4^(=X)dB-Qo8(RHImICz*p=N2Keq?g-~o^HLt{<}u!Js2|5|9<)y%O;SCl!&p&P5kRe%Zisxc_^>v#h0#48 ziuiS(fY;|4sc)Pg#;-#VlV;6=X}n*eQ`M(Ha*%>W3K3I~gtnm6FpU`HME~9wf`#4H zO{-6VfQEp^8AUkhm$assd_MqKeSx;=_Y~WQJBpv?aC^F&s?k0dI$&i-_=0g-)C6|% z8q>TZr?SS7eEXs5DM-{!TyUAta|y3w1q&krron#K7b_G2^&L9P5^o}R7iimk+CqD?iWoHtRtMz9^jOAYDkU+!)KUr&mTMzMHJ9PU*9N^`MQ?X_30lO`W|_8xc4K2AxVcDk>|;#0^;jz? z?S;2%2I+hj-Zkkko3^}S&fG5E!pbvH^H{SiEZdPYb-Pt zl@{70ie2M-WT`k$>CYT8eth{=<%v)6GPMjpxyoaWyDk?TKBZhOT?L2g1OP6I}s7}<}! zP5k86?lxO~VT}gr_wOhZzzg3rPE3S8xjNWY5m@vj^^Gb>emJasL-nutNU}J<=g*!- z;#C{N`R>%EYn|peI-L!l<(6UozL(5qm58+U-h^K8?4;r=iEY|W)dRF5?Q)Y%Lr+`I z$ybx&Z7zYI1eC4Z946_v>4k>k$`SQfLRMoZGSoj>qR1<5VpC^oWD!_%eQE>`kFqk8 zDCm4P>sC{Ws5kf*manr+6P-uiDE{ZM*?Mw}AE}X@T0*Zm=39hI|K}OnqJi7OHGs@Sr;o$^e&afRM^$P6)HU z{6{~5BYlLUz0Hhr)M@c+`ghqSp>P6GfK(Yd!8$+Y!xo6#o^2IY5Qz1jkk(1AXM#23 z?DR=srOU7ext60BVH zrNC4u6y_83oWInafM7&Rw7q9M^a$cpmu5Bq!^5cmNYbjSbpUn;c^S%nH{FUNmDbY{ z8_>!^za}f_7f*l4DvB3}^N4ct14;{~rfRrLyNA2|{EC_pw6_(WX}Pp+3(eZNZug;F zb;9BfXTptOT|L~4ptaC{+5JNQn^xR6Vwf&X4YxCVdp5gS!&O7sojqE;=Rc{yE)Mq| zV1hE8F0?y1N|sx((@-_=%Plt!dgiYC(oDZ7!O+4s#$m3I#VXkuH5n7eC5BbH{^`_O z=A&~LnHmQ((rGWON3iv6Lp<|J5D))K_)nh-A-m)R{)k(<<6z%pv%!Ll!M3Q&;sQ%8 zy^~sx>!Uw$rn~+#D>W_Ei40iRd()$h(8IB%c;BaPWVkIyjJ!$^THR$}Kqi?28knh0L z6#t5D-$xrZ8dOFlwS=DuH+{0hyuU?W1YGLUSV|AMTNrX<72y!SjMBM$$fPLd%0E+f zlc0X~=R!-9ZR6k+!#W5X&ac3z=K>*wHopIeD+!@dxFtrCK}hCc{zE}G1n4K&$3o9y zBo!FiGuod)&`&TOu^}*XnhXpEJii$=gxVhAHBUowYq2pbv1D*KDw zt0hq)*ZPIEBL`J{+<4k$<~fb~2ElwTg_;euKKly4#TOzF&&B`cj$HgDdwVGTa#Rh{ zU+#KxJe=TOF{r`u10FN*u}{vXB&_n9CN6gC!Zy}oH;*%ieQ66D&SZquYBeH=Nc4LD zL)=-O*{Tqt`6o%jaUi?Q2Caf4`R1ikGyec48{|R58QS@zRQr}!RCkqYe5?8>@%wZT z#Q1TyZQT8qzSvI=#Z1iZ`tM$2b`}!zsK*_c`5p)BSL+Sv3R`S98@hQUTBUgvI+QB> z`KpO{_axwcW8pKDCF-*m7P9=w^53@mV+6(UHh?l{uSq%dap{$}5v#VXr?bm2(~mSXrhpL-{`CdeK%~#s6|Z%uuW(dxPkd zHpX1bYA*DC!}o~yGhr9%KFBL=oXhFTpv~C$D1Wn_mV%mI;_ySiFlEu)6rbGHZw`uc zoWI!LYcjQ;X1zaXS`!ihx_ZcRo-^gZYgpFN%;0HLX}yPk_(S&F>ysa`B^qya(wvKr z-kX0`8?xhwvz`!6#z|eE&3u<6TZ**P66Dq%acRb1 z#l zL}O=MrKhvdvy`h`yG2j6d-Lx2=u;`M3c5dpIe<7avvEdy!8m$!wmbMlH- z($%1I+|`e$3s0=KFCctK(V3EkX@j;SM*u6qezNSdD?e!w!d z%dC3lF{}m5(Yy-EHc7pgZQj^2+h#r(?Vf+;TccsNM0vv>2Qy8SX?W2c*rgQvlH#Ar8 z%|zF-;Vd$3&o^}kI4a`Wf?MMcYSN5GtV;@Z!b^e?>J$3SM~QslWPeMHLby<2<_OTpRLW81*z3w2^U2UC(}2K zlZAx~`v5<4P`}EH6AtNX&HiB7EK#!{YQnj+UjQ+gIe(qcU|QwgzuNrjwd;*WO7yAN zIfn)QGU775mI9yg`WOt2-14n3+x2MK%nfIxxfm-|sYji7rmaJhwArXrQI?jrC)jaz zPD}qxs1{@5RkV=1Fj;4)aw8?)Mf#f!5A2GlidXO3YYy;#_pc`gz|~+t`C+9iDm;^3 z*ZZ~mAtGK|9)hEM4u(F~xf$-lr%lMUOv_`b%MN*#$Zc|LX=U_Ff!n)YPcntN7Yb&h zMq9@0k)>NB!8yq~yL1xzLZ)`P$|Wo;rAlK$`>mNW$PWr z78V+A>{Xf~xpsU11!9-YTF!oeG5y7BD9^p9nZe=`skhE+tRghv;m}QWxxp7f40uPV zvgQg$sr?R4pS5B;QyablbSAhk3d0M2J3=9080A3W4NRwFe0?icvsTd=N*OnVh%IOY zheAsWPf6L*KE$AFJ4j}HZFKsb2e%9>Kr781ffAPqpBASm3hE#VS2Bveg1Ju(_p(|W zSip*3^qv>h&MT}WbZFTnX%29oy{?~UE!-~G?Jx|G5yVU59XEu-Z$MZ>9VM7h_>f`5 z{7R118pAAuX#3`5(=>K|EA5lc$0*k{&R>t{TF1r6u<#C^mkFAq=tfjmqjj{I-1atb zYB4%QLO$QwYR{3YIt2;Q@g0|;XR7z7H^EliWYbL!OTO*`9o|+G8_i9=vU+q+=j|-T zPX<>4hny;{GA8S-4%t;J$M!lc{rKu&P@(IpyzBi5UVltiUL01YzJ+x#sNE_oqh> z1EV_Q#s4hGKNKcZ>v^A32nAqr41Gjeb{zTHCiys1o|on1ql0He(c#jlY_-08(?*hJ zw1xkl+0G&58-_}S=n3~HcRjW#xcUTF{9!Ohl4d}M!(P1Bi;^(Q#~ECAIG1AW$TY zU*_uaVN-7L8CYdbWfII4qV0*fYm)u_fx(?dN-IVS09jBDRud5kl&lz%U&I|`qYuX9 zA-Kcn>m<~ZeAm033y5dP7L&$>pFW=&zYg3%M1)v0{!CbQa@1`mT_(0FaS0JP<>qtJ zTKR9+!R+AIY|u!f5kjxq?xM2%NOL>a%6vFVRZ`B9Cq0kX&rSP{Kdb(|t1m9uyC4Sq z#o2bVH3pZ~vrB1_RfcsU(@bA;GKD7p+!ms56xL(MBUfUlD$OjjXzcM|B@13@^Ir5S zevrwoD!WBxFzgxfbI4wlQo-!ZGCmz)m>wbQMDY7s0k_@BeTudj!y0`58I?eL5}@cu zT&#YDplRl~}WM zEwwg*_4gJ|44fU|Yb(Q9z-d1QMbLa<9_~|St^CZiMex!A&cbbX^5k&IG}BQ)6zRKg zTEHoZnnwE;7@HnYjFqJ_Q8aSFhRo*P2RPR(QR4j5fRatOK&>;d_wH-0~o7v?B z#6cza3OLouT#l-ZDUzaug0+`oWKn&~K=T#aU8lT&=6N|Pd=XTkdR`Uw)!ew7z3N!eiQrTk* zX*Al9)4%1s!r57e$1pBvXs1m$;6V5KrEOyI#sU6gn^BmZmNT*_PMjVyQ*}INlx=Ph zW3*5PPvw>Fb#gbS%h)ODDL5+M`l`y!BhyvoK9K1XdmyKKBy|x22;8aEE{$>SX z5#OE3_;S7dhaFv$FXZTc9Iq;bcX=gO^hHq?g}$)ugx?ECVxP4%MQ zqnYpV#?@-yH1CmfIr!W*uS3gXfcxD+udnalhY^OPW%DUz`3>aH&ZWP8gdPqWlCFF#KBrTJSqB`w5)tr8)&52b zS72K6$ByZSqr^lcblqct+W84r3Xm-bP7`)aRWDT#WA2%?uX4HTm^j3XeC}<&7CIao} zUCbSyv+jg?moT3_wzoqr-}Hqw2Qw_1+Wk)`X1@huVDUdd5F8exkvD? zcvT+L64{k%#(JzhoNlpghlKK%oNF+zk@nEP`JI0r&3B9FYJ6^Cd}&D=zbxEu>~{FB z2g1|E^CL)@PlVN{R433Fxqc*L%cPRZfAwO?#?dwtn-^&Lzg&xM~IpkX?w9rrJ`gmQ>v9gr9qW70QM#FmXl!{(&Mehf{X03#7F0@iD z-9y8E3B+tpeG+8lY`^Syrn@p729Z|?ojluJ{i>DDY%L{MQWt9}9-~+=-qSlquZ?ad zRf8evX0zMfryFg|r_5S4TH9M$v^jhAn&?i9omQ5#m`|l6ygrj|9ej$kkMT_Y*7y^T zjzt5s?}|kiaf#2niqW;*eC#ZS)$nU!1!?U5{WCw+$(kR~S8YmtQH9K^+i%N^N3QR( zWsrv8^2R9s>&7q*QxXH6a2Om+)ZhOdzp=;mwHvqEDb=Y|b?%T_%lgjnJz(g{lh*i8hmW2TlCAw zc^ft1-Z22-_}5_}+cJ%JZIu6sVPv%F&wL+7!$^u#^)&0lrLcW!Ew%&4ucWlVFQ#)#PP6XxAtht-2SqbWg_L_MP0}&S{8-g zxDTRnlb#!&VcDepo8|K(CcGt|ISALa?K$1)@8B7^`Kr`}o@q#Cv~au@`g~AA+;t|1SQCA{%muvbL!u9pRpo9%k0-3Ei*O-D)}u_mx0 zom7Dpy@vG~@LTrG!Qm|}E;XW`kGJvHKN5YQYs~T1WBN4U2t#P(BYo`12Z&0{=ndi>j2MnB$<$jThK-Kl0$V+82+V^To>$@1gr@sUMOB=h6mN;Jk~MkV897=H;@Dm z(!{k{d+zZQVH6<>BQ7k0I!#NagnyK!XAq`I)`^j5e(4=SMDc|y%_zVQSP^lD19vQt zRBH=mm z{WV^8fXnvy?fe?=Nb{9J-3Y^PP7X5SmBqcLHBCe?T9=Gj&m84-$qOmkPG=axnj05j_3mi#4LbfSaV*s*GZuPn z$(|8L(vJWqpZ%&(=&zD+`)Kau4195pHaq`<~McCo4gC*4fWDw$dCME7 zY#_t?^ZeR(Mq@NE2b=fZRSM^g*Dg0ElSkjgBaeUlKI&I^W8UP<3lr`}kTAmg5O zN@lfk_>v)?0^=6#Wvt6Iy{-Jf+N;RHahd(^k>b(6mHQEcb(N<1gcrXAou zj60jtj1!2hrVKkmlZY!+Z&)&{NIf}Y->4eaFmJ2-C~d|0{?xIgDCd>G+kX}$ zr5Fn+%BA#LZY7M}Qwx)AM}JJqWDexK<|}du(6>5~x+QlTQ0dIY3XL^$JkaaWA%9*3 zn8j*?~9KyF)x5F&4raAz4CCf zG;v4JTTwv4;;a7$6br=7oWVhMHMzg3B{~>yDn@aBn*{}Gm8=z*uKdakBJxA_nvB4r z!OGYP&qJ|T*r_m~4Ka%BF@m>vO{$w`?iKm0Wvlk#B|+^l~> z<;p+QW-howv$h6PujfrJKn*C*6&TG-K_M;PtAd)?ri?6a^>}O^w8e^&mDb)4_I-CPwruY ze7hgJ?9Kz^pGq^F3#Y13hy;CpEwS%SoQ%7r!n0rhk)A4ONMtctn0DhT^s5}`o%~K? zgGz$|-=3*Zcg;&T_2z8X*!Je1)POPeQYi~coW6!xL*GV#iFMCOMm@V1 zI5b!Jp|mWk9S?rtWV<~<$C>=<)RQkxBfMjabUx#aX27W5U%ULeI5%y5qob$eN05w! z5VhAm5fGBE1n`g6lBs`PzwphR^`1l)MBVb6a5k2I7n8=BgRxT zpQcMkFx;W1Ioz&0aVp6)D9+ny7ahCEH#WYn+6 zb2eOvILhdhZ!1-GryyRzw?W09luWUg7lDlW!*0n@S(eneb0!aUvENLHW$FRZXrKve zG>59NeDXn>dg-IQMYv$Qe=>9F_PQ9?%!l$G_X%XT>>XMhz7y|h*$8IkuPD`jsUIw9 zhWM={l$8TeVznBgn`YIyE~pQ%hUgD@HIkH~W2dITr#?4k9-!k z5cwM(cNnKX$jGsVMuFT1X+bW9@P%r^aZCZso_h$MhWNn2dZMy>2E_G}$cU{TmEto@ z?h!y(SVl$;z8r_SIQ+cO-16Q6QvvSlBtirUt$BQ10m%Ph zI%5aLv773K>>w5~52{ivsVC1moQmUN(fu3jH#xOQ5QJ>LDE;&JijL>wxpvqtN8@<55pncMD!8Q1t@3qNs^_XaP_2P=eL#@S)>W%N8<_v?XhW)zF z_?&kxs*^bbNhimj1G36$I6lpGEIn*CydHEfTGmXWFLyZ2wM<7#36>trzjY?3F`OL?$SV)ShA%_ccnx_-|J)e_i zD_8xzzfMe1Q>uH7Wuui(o#5SGO*!#z#HqIm+?!$h(S{b+StsnB zf0i@hX2e^$7b|_7eiO=($qH-tRu{+CG+z`ZFv8!t6ga!>Oa!AO?-PDyX|JY@#|f~L zK!2;>%V{H;*}IN+@H2t}21cFKDD)X9C%#WZ8?B&4*N>s3!-++i%T-M58F(i|3PqmD zm7b^)0hVuyA1%h6=XnYZL`NW-X0qN8)}d$c$(i}e)Q<-?JuUdacTx=Al@|Zat#Xx8 zBEaH(CqIiIXMFlZ%_<4SwQ-GPwJb;sF?_{8m1ZWAyE+k?3qSb58xKi=?PR7aU=;+Z z9-9eY|DAfNTPkug9IKJenp!Bb1D@hByJ`h0YBE$3_mrkttDOJp*~t`EKpyaRv2FJ< zAR@yRZ|+0ps8VxV%ED>h&!b>6^`v?n8-j0%|NY%k zWR1R+VYgYRKi=ByZ0(4lAX2hFa)O9F-zMhFDQhlc5-!jOv`LLH{o9!&k7xYBDJ|_9 zJyk8ajLzPA8fUmFWc@LBFMH{eWow+C6}izR(K*?lHaTh)nNl#2=pGCQ84D24q|p49 zAF4@2YX{SZ`K{uNvGN71m+gBt2r@8WZ+^2H2{dJ4YOjD-YNG14oJqa~vf9e8HQR8u9Z z*IQKnnnz6!%?uEKts?D^?l^~{L%?|hA!+DzUvQG%S?+j3eqYLZ7oy&MmG%N5495MH z$dgjDR$p6t`##zUYyQ>QquVHNw;8^_RfrLGDzKEa1)%r|kL4e`G=YZd@A?p!(Vyi^ zv%JdC&6jua{V{4-d0};)fj>}CSkkt0ake%-zcBciX>}Uk&ck%^*FM_^()xDfU0wO@ zvD(r+Z{zwJS?sGZxqPnOnX8wN1y&KgM{56NeGH|RmKe$MnNlEO822m2C{_PGmBwlu z#4)n~Ac)+&I6_EZ&PQym3?$2hfP^p78+$!_Ec7 zI1*0Bv3wQ)Tk^qx_nOXd9GkBAxzn!&G`3}ra4PUoEJ7n!5HTCuyiAOQg z8-TboJ6`ExCX0=#v_%Q@F*iLfpBA|}YUvM~eqZkX;F$0qG&dd@bxx{pl%mY~U%gZ0 zi+_ANVA6;F8RcB0us#E%%?`0`{oD? zdC6?Qjm}|ImTHt!LOzV5O=;VWx_{@i^DnwxxKq2!%iG)6zQ-}jmDfJ;zh5I8|LJ{o zZE5s2h2nTNn=)tVTRt)Av^JhrXhepme0$73mbZlTCq46_#Ag$+K-gn(b`kLx_`nLv zmw|M3_Y@6X``;jcWK%i0B(99zDRudoEi8@ z#3C6ccuvJk1Y*l4Z;VpJMSiKG z%&_{VQra5VpL$z~rGaZ7zRo>6I`}ppUgo6#9k2}y$BsGuB~AU0W+?7IH`3e~TZ81~ zCy%cR536)LvlS}b*17At+^F$_L?4fQikS1yGpniE856BSbW^&FriNgUaF|yTeLBmy z^6X!mMIjBY=^7T!=*IPBBVG=nYKfze?FFS^*>&RhlzWo+kXLNQJYomRxnsZl0OxuG z99Vp@cHSOgupfZ+DnP!d3=H0Z+u`O+Tsph#NW24W;6ztgW^D&vTHS10@J0nY1QLtZk%-V3ZNQ2%{VB1$M44NkdOcsyj}?&F8$8e5dCz} z6^oA*>{Nsmi0l=S_+jv$Pl0$={Sn9Qhj^CBr@nQ%0km2n#32#V*rMgIPKIbfFbF3mm>Tl1;!-84~6HJ)Fc*EOI&-!cjd7*XKB` z>`ZJ2X8*O_r$mj$3uI3L47(5TUknc?fAH`8<1&ZBvg3O{TYU=z9w-;mz)(Kq`d;W< z(~?B~`+O899Wgs7b9C*mmvI?8l+q{dA?njq>p`5c zjh#WldvkWC&eI&d6sAwze8LB-s%m< z3f=Zf%F<9$)c+Pm7;;2G$FAiD$}j72i9Sx2XdWhx;01lzratBE(=?eeG~dSa%q9cb zQrCo68u6VWjf>Of62{HG4X3Vf5Kj?7*sn^vmpwhlPcuDT^_9_9OCiC{wy6A)m^w2O-4&*a8IQqP zOkZvs{WSevm9c=>-_7;7>JumP&(@Yo>gF-`*7GrQlG0*ZC|BaSR6zO7D3-kOA=P3G9ArWXX#Jo)`1?_8)-PP zp*->^*arp{7G!29!Wi`FGjp@!siMOw32)m?iShqs9ZO0Tf=v@hwu^W%WirLuv{ofKjWnAL2PG8>euARvfW)(&?uGRrZKK?(z{3QcIMXRr$sZ;n!K7{kOx-1eE&KS~X1Zlrv|HmS%qBF$CmRM;ZW)EgAJ1luC&v-i?-w*1r3%dm&}L2ve+oUKdrD>rY`9SUDT zZDks`TR9t#bFTn)KzrcD9%s@ub&Wsesma#^SA$~r^ zDIX_+W(j(6tA}0ogvxaujdfkdy&0zW&33I76ZX@#FW#IqsU(YQ@}Dv_7!<1xaJ5qw zzO42wd#}Y~n2KEXPLteiw^1diqA{vMho`xazOq4OZ<_FQ;)k2_%>zp>Q88w!@1?*8 zjv3J!*=Z_PmrVsPKm*xGkY{$v}HuS;^F_~$<) zG5b|@jn!*e>C}3+0zUB>7s+YH_sT2&X+Q5=Ott-g7Q}NhT9GgEXkbneF1pPs6zI&b zD>i7pyKpfn!(;1wd4bP4$*OG3#sB`2-87#eLJ)dv#&1^J(|HoQjN|f)S(vZ0 zs5}R=b)4l(|OUwU)9YgW0JR;21I`V_uBFerHFm!2Ftj|SG*{t9k_yC1-bP3^b(E5p z(dkzE>G7(g5I8LBfa;f)kxc#{OvVy~f%02zsg35<@XM?l5eRM~KzO<9Z`n zztWFdHq{ssd0E`{84I8GDjT)JF$P;|YE&HB4!F~Ko$}6B19#|%1FXt$6q8GG<{jE9 zU-|K7rx^F4QX;^)LKDObIxh` zs263w18=`A{LnDn!DVHs{8Z-tnIg^yGO9A5IRo$b<0N!2gG(M@Kw{Pr9r=h6tb+n} z?2G!M>r9Hc5u{&x6=Z$dEj*ZVroXj}kbh`U~c5+}I%hMS@q- z>GK5cfCc2`dXC$)4s*phAf+b_shHU>{*5M~leiKDS5rqA?5TAR_`@C&M8sBB55{tP zNGL55Sz>K_bpy=uZA4~y9na&S&oVhf8oj?b@W_aY8QPEyUNIY4B7`Y1BjAZT6j*Gq zp0Lq(d_jcJ_*sNoI?4|SVX}~hfe^+9-EUw9CWHR`l%wX&J}bO{TrPP#@?86av~mNm z_}}|G>{9noGr+U~i)>}t7G%ofd6H2TB`$dkH-J#Wn`bw`)SUF}nbK{tYk8jn+UcEj z1K)i*|F^BpzyA-&@;1OwwR~7!kv>thihP@%1=6qzB+V*F!R7q|M?;Ke<)B0-p3Q90 zH*V{3Y9e93ANB2}K)7VF^r1YN0!9b^SrlGe$`^_i9Ps$weV~3toCj7+{fE#M_ZjL5 zoX+<`?{f#k415kbk4By$X`rjUnriCwY)V=OU)GX|dQj*E^M^O}mLoB$0`vO%5b{X{ zs-o8IS+`J;dsydsJup(9$d9VBLlQ#Z%vci?M_4SXfc`6WABZ3c!^vew(#;c>p0kFf zs}Z@JJZP?)^RvS1FPZ;7r|og2c|r?xFr7ns>C+w)9~h#iVNuTK&6tD+rW$;bJp}Wc ze7hz2W`Jr$R5=w;{f_fULB3KdR-q?qj9AgKj?1Lbu9zY&6uL6`6HMG$YdbSIH&MZT zlM)G9SXihC43fFHj?RBFH-WxHNTxCh(cO4COB5>72-}`0j(s+moq|h-#!Sk~$(1F? z=qKGmS2!H&hqx0TAMT3%jMaXG#96y;Dhb_~0n)BjWGc7N?|INcHyEqyle<7p0Oguc znTNx@Glov0A)Nc$)s<@IHY?bM!-eQ_TNkg|Jj0|@IEHzt7!cVekDY1<>hVD+R(JkK zuQ4$g4r>xXSU)`r1lNImH3d*`sOd}xXsn?=K>cwF@&$pdYuN!#aSlpBfpuy#;`fDh zlA~7Hd@e;R-{+}?pt(5p?gzTHB|#@$6RK0rw&NlogZTx&EYAL{-u;ZQ80e1qYvtSPhRgw(-ZX~OIoXQ#JS|$)dSIA=D z$bbsZ9r73*N4|SsYEb!XamgUZvmr0P5t0cq z5s2r~K1a!T=lgSW66AVNE(O68J^Aw!H6^}6Zi?m~n1Kz?wZ(=ubIlc3iCh4!V7C~2 zSsds*Yo3ZaT&Flr76>My)Sd+!e5)aN;~ngc+QHTnMSTD%vl`BMUu2%Sl8J=pbe2!p zA#jA+XvaPkLG~#nfdXa-VZGtRY`iwHDWySyZ)gJQhvck58@5!G*PbGPwM+L*gVwx> zDwphK+QSe7e*&X5T{C%7$|zBh+o?eJ{rmV2pLPl@mXhb1%g4vr)*eCKs}G2N3V?Gj z`Ku$HgcO_@E?Ka^eob(e=YJ9L%Kbq<)3jC`)s$6<;y7O5Gng-)49NHtK53F8$tj-CcRW2D4fm{o`S!tWtFOsjibeKz)21b9i8LTxa%|Q6-+1&)EIZ0 z0ZCgFgI`J-MI6)fN6O?ex0}umH3|w*<`V18FAa4B*@+mO3p=#&xgC?!$mZi-_$F%U zpm*E>&I&llpag7&Ldm;|t~2}}oO<_5kUhKkP?0jq0G&1*o6=7n6(7c6$B9enHlLqM zsXVW51`Ho5!92Mu=S#Z|5M8JTfu%ed&MXWwP=b8)yOXKqX6Thd$7&W;G=15unX`YAVj@j8Aj{i z!6|cS!w5_ghr{F=6asZ7S1~v-COW#m)?>wLEv9c75^uEh-IDEUe-kz%*wfzN_iFwD3*xmK@VUe@}t zN~d1x5&Xpgpz;Yxf1k(>InI~rOaK*X5^639II(9B5SPMlW*!i&d6F9u+nk7ujmvN& zfLW*d%;RoFd0JG7)nqM$x7Y3#_r{Ny96N`)`ZkDxgSTRn$U!N^6e@@i0F^x=ZUoU$ zKbTOW03S`IsExZdJM1N(kGgJ;iXwv}iZA=@?6J=QQ~0g>X&;@X*+ZG$+bnp;)}124 zgZfrDp5Ti_`)inS+32oc@GnWss@^!y-fLOa3!$3Cu5Y*F%WDpcfvymQ4DXt)~_TQ+Q< z>Ue=IE?aV7LbJ@vZCC#i*!B2%IIcseTKU_vo=Y>io6n1j3kDOCcypWrV?ETzpbXbLt>?%jaQNNSguORNJqMWcUIh68Sy+G2oaWES>-XJ*kO`B- zT?&y=ScCELd+X;#u`w2|D-DWoVgfBdN7$RG_ON#b+^F#8<%f;^9}x2orU^C!Zb*2cb8#hE0crCW3gb34}GafK=8JlPl=ev(5KeBX4ZS zW;L1{$zU&y2_BLzG%ZxO(WpKOBd~`u!2fN7=VAMugV#=BDsEk`bgUHFtZve?;GN7H$H%w59tGB-pwvo6sJGNGJgAg)muMEE1n=Dnkh&n(6 z`FXeif{+NbOH2WL*CHz*$BJXtZ!NHg41yh1_j!^x{hfEyGox0jsIXhy(p*6gq9D#> z@0d*>IDx|p0Fochvw=i()Vhq+_k1kfU?Ztw85r-@!AYTW(f5#-Jf*J@66uuPX@v<% z8=dc=DnUhasfK=U5s@)U?hyn`5h3Iq2l|Wuck8D|u%ByiTIReL7gGfX7^N|tK!s!$ z#ndEoVd9_;I=!^eAN`g=d}FEM1XR(HH}dmP+IeGW4*>`U{zEIKv4HlxfLCaLrW!mm z(5a???ehDzg;A+SB%DR$wcicczjdE)lPjeCW|L&rbwW{JBxu`m76-PHO?QoCkt0>2 z@sQrBWyqhoqyF>Hb8J5cU8zS^#k42lxKTdvHZR2M8u|;s@(U6+{HuXnzXAMiH}W~o z7yy#FuS&n0>p;*S1(srK@4bqZ*`Q8fhT7ts0x>j}bXhhC{%2J$bgL~vfUz=o0chH; z?Hx8hMXW!-aZWZZy3cb~i8@Ec%+isXa#EkHncxZ_Sd|&GR^9v_n{Sn}L zalgiz8$l=W1A*`C`=k5S;i7GZx@uJpzgw9g0Mf)jdXCr=j{s>_L2fDKIr$7v!{+iv z!wBRQ$@PDF{AD-syzsvI5-RqM^Nri>3!Eo68XB7aS*HEXZCa3@mF7d-^Nc2MS>KcA z5vqd2L)KVNlPve)EIyauaF=I!8|fG?4Oyz0`cf4(!^cZYr; zl_eF#!5Zb)eGXcA1kU|QZ$a5NF=@v25!~MONQSC7fB=^V_TzO>u1Ezl@Qb|-Ry@;} zBnYU_aR>z7wvQO$M9K*4#)%yd2acy87w#2)Ji+ej^VTrCzdi{fpviGV6ZX-Ov;ELjui>0 z#DF5t;`*Qm+q2CQ@FCaDvo%ws` z>gJFjH-Ag00Hraf{T!!94s+{v9&yp@`HkluXLO4bfDqI81TU2F#w84kl>Xg}5-Zr} z)+qv-M!-T(iLCd{&;>ZkzCS)!z{wg_z&`4y^yjZjd2bXis|_ar(=v`ZlAXsn$!=JAWbMG zL5I1nWY|{41F!RpZVRL7^I0v}$1{)Gr`{dF{(*OSqpZBjdAQ$NJEJ0(%npW(T@n%#slr}=vMR%WYd^3`)h3FIgk+Lt`SM_(ewbhW z5UlE35Z?DAVgPYWinBf-f-kcak-_^qbh4~eLf&)>TvoVBckwdFlXol%rN6wSNDIOy z<>#b5sN7BBz?A~SG)bW5k;~twu}6Gr17M-vWDN3fL*e)LK3mnLbuI_r!D~;A9SE4V z<4CmE;C=TpKQDDfr!tA&-uwKf7aCUv%0JVe z)T>);aP2@)p4}07Jh=T&oz^P9M{j$OW6x*uy)+-n$%&Hi{P@`wP7wQ>j{DOAWQ(X* z0^lZp4phsd{(-SBE-|D{eXrvU7NU)BVXq@Stt-qtB&}DZF{81vsJ!7h22FIlyQp8; zH%Z9xO07U=Q>;$X616;uC^w>s80W0}-slzF+vk8g24eFZCBPRWpdF<|{fqibEC=~N z@(&-oY5+;5ZLysN&rhk&4=8YEh6meAN@T*3BM7}UxMuTx=XIMMm|9v|NHl)u9AT?Z zy7$aIUN`*LQsfT+Zc)(*7%WdxblWjj2a!kO60NjLci(dwYD+~*R)4L4MHIJz8!+U} zhM)ReyTL9m0y`Q1lmDsjo zZMG{*$hVb)?-|Ln;uxvKm?4;!{sub6H!=B;)u<9I@RyE%wrCjw`Fto`lk1c~_ zp}JVS3%^m1z-;@r*)I;1)j=Z++{i704!t;6jP){xYkzNmUn&GE=_y#>`vK~D z)gp`xnDDl?_Q3|=638%0PQy-jguOlj^2t2~cF#wudAhfa;C8P#?fQx3Yt%X5l z;+Mx)M?&9dP(7ki2F zg6uqduE~CH5P{5lpH14pxM>bx=e3%x?3qx~|NXCQH-}35W0XEtf|m)H51$RPVUnYm z@CUCXRsrqy=-zwPotlthS;kj%uF=Y#=%Pmhq3891Fi!oB|9ExyhQY+r_~B#>sOP=3;4MPgBEh(l<@S%WVf0ed1v%Sq z*~6n)0{gIWCA~=(Sv8aciUaCa7uNt{RWXJFMAs{Cu#GWelD-OSs3#sD4!f(w^!Li( zPb5?wA9(Ov2}D`Am=lGTCSIJn+=t>~9)3E#$deG2QPf>jKGm9Nj!S?){B!^fa}8xK zpiO7?2WFT8GVC!dr)|KV!?uPC_oTM8euE(QDKtp|b7$}f*>jumqm01x;bW3*oE6zt$jn~R13N5Q(T%ut%Rcqj(yPw-t+aFMy)l(ZCi2A*G& zzhk`jI7kWueOfP6mxU=vOF|~?-m1?EDD$trbYgOgru8uuEb_@r3c)xT5~05f{aDRe z=OBaPaOksSzvM)tvUn8v_-2-PJWx}z_#fNzT0sN3#u_Iqq1}<9QNiu;O}(c5+;OyP z%GA@G?T7UD`j1!XerB~m{p?xUauw^Y&%(K7DOH}#h|9F;jSgho1KgxaMa?k%mKVtgDm+6$Z zft$zqgWQ=fV-xA$405l(`ms{z8B&Ae&hLus z3!+nC_2E`ateJbh<=>-hj>Be0fjZ>-?G!mt8)pEVXP!R(>%v-KGGw+n0J6-iq8G#p zgIV69BpA_Dj?)2usEV+y2y;tA5e>eg+#juE<@k*1N<+;LMAT$n&{_m1WZ$M z{Jo}+*mS{E)iupN)Td|+bqFjPTVnv|pPeZoIC~zb!iqz1iy2BIV z{oD691jE>U$zPeCK4|8Te8Y{cqQUxHa{M2Lj3e82Y7leA~jL^$tq{jc9xf^^4rw@0QX&4EOr zn=9n4@XIkC370l{KkNJpr2Iznq-4L(9tR?%V;_r_Y8Px7Uu$>184J23^}7aYiA<$V zYR>!P2)VmbJk{Yc#39e;H$%q$xtM-%XIjVsp_has@RQ-<7lh$*j&tGo)Q_cOqFJ~W z$XjwGj0S#7j5NxSwnR>L3yFC(M%qm!*cu!tEb79{KN&|TF-nO>l{aU@E)2UKbLvxMpP`yppk2NgggnEuh+MM!^IfrS3Q)1f^5UT@h&*(nn50;;yn%_p zxS*RNqIsXs*`!g0IyVmE)=vrnug_7_Z9R``Mt+gZxj36Ks7jLA1HDnE9#J{n$gj~U-wg0gDNmj`Z$DkA)x*VIe*1G@&?6Z@cJ zOLl~(_i46bxz|U2$F15OH*rp7ZilzB68MD}(8IUaP1i^Gw!IjXO47K4$H3BQBkec( znzb}ymU{EN0Vk;~&r!pz-TuVJzf@@&ugk%%QS!X6XGbCV9=4! z13fJxgN<v{r$zr z4T4%F`kX3=%RgI7LkEcq+P&?oIC zP`tt#X{7tbFaREJHFUnTLTY3P8ey7QSwOn3o|RY)ZGs)tG2z~M^SG)D=4#gu}xsO)p_vt ztncQzpK~E9krjB_YOAgMhzz>ctCviTmS4T3VuWtD!;Ami4r$>z&nz8htJe=ZFDF`E z<#&Z_emE9D^1_!ro{zX>S?2EbzBd|ADV5EiSo%LiT~%0=&)cR$KvIxyP`W#%ySuwV zQt1)|k?sx&=~_yVknRTQkPc~({$_vwgYQTWye@a&otgKUJIfUB%LLXMC7VQN>I)iE zT=)apLjKi|mha#tR{Zl1@n91UA>3tV~akAxQM^c6&TyZ&2C^+Y4RNe{2@e@ooG2E+~ z;^5*$omb+cr1a~yAK0h~@dP@)pMS$3h(agg8c0{1N~cT{pBVIm9EN5vdI-qE7qH=r z6SEk8qfI#s*~Q|i7!(+bil!JQm!PC6fc6+`ayWIk7tXGbIh0` zFl{@U20er#?^kRh5*_*Ms~n4=*gp<)@mc1HJX>qvg7(KcvpiF$@Q_V3U)l7tx5mdF zP7)`H*KQ;uSP-@loI#;}^4NaClj(DZq2NAg)d{Z1?N)@+=swA2&1>WHl^6CqVJ0pe zP?YK#o1*gt0{+-xC>;L|{qY3OFAwr#gGFodB--C9>x*DZNoLbDW9$FKB6umE)4Bj zFOtn%9r?#UT@3%9(BAKO`U2&EY&t^-q2mX2^uRsa>5VV=>5SntM@cWRItgBfzCLk5 z3S_ZmKX>#N|Au{zAA-`=hN~eaFe? zhY~p)p*?vKAU)+J2dUye#CV&h+oTfOK9BfRGUOOtv#)msQdpT%yf!wTLRSg(-w2W8 zJRvT8Z8s^7`2rqa(SkCMeKa_zn+Ewz4vchByVr+ za$$LVvsO~}y^{~X$*L$2X@;T242CaYfKuXPvi$Bu2zZ9P{;#2n(9EHI1O=vve)tDyAVD5=$HEuuLa(qm%YWk>ZC`~SN<1!PNTqf ztlP9tVLrv{wl%=;q1b$sdTG2H9a9NDhg9GM{nKf(bU*GW3x2fXK9b-vat^m&o2h=t zH?slWs@|UP-9($zU?dv+@rs+w-V6BPK351sON=s0AzmoAbp-cfCUw(<^*hdBkB>PM zaZ!>m7AakV66q7+JtU~-Uj*Vr3R&w%nMSrQl+P4NJ!jNnBscl3@;W)mjKRDwq(|Uq z{IP^$|Mk(vcXD@SB+t0mHj_f7{*}zH>jUWvUb5!VANLh?_eL~avdlS~gH`|d(;R+ZOuheJbTYyU3#Td_wy~|;w4XOrsO7`5Mu5&G#)fc7)xT*82fQhg=V(K; zeNs91SIdN0f4ax4A464QorvK|Kf|1`AB(KvwCg|+{WABPPL;Mmy44u(4hWV1ux1=V zI2Jq;+_TPi93Zv!U^+UO=t5EaK|J3nj~xE23js!?{nz-}?nUL+l6+vW%WF?D>KD8O zPnin22-EJ6`Cnl!R#Iy`iuc@g-^5-|k+GlQfonh{@gjWtH;6_OY`tvzu2jj zCMF_Qk5A^W1n96{qa$b9J%`Q*^_Zh{+z*iIU>q{ea$;t6DHxya6*!Jbut{`zG ztJ`~_viq_7L+Z*&68KnKtFIo>YyIxQY@O1$g;Z;{SYIMA$JPUWlS2m}Jp>ACiek3l zD6V+b*^vJ8(OqJK2W{jF(>nOgxBA3*LaEnZ-2G|H1JTdPOBHcT8UB0Ww;u(NR#p}< zOGIUP{a~QM-rn`QbBL#t@N1u(>$*;Y_?fUx-KL>TD@$OV3r#dm#adC`m8G8gV#E(! zpb!%5-{w7#`MBYHX#VO01AC}!Nm zhaf}Qz)mcfU>~GVfNfZ^z>U1%7?3Ov3;qWx3D-$>>FWC8ylj0oIxsHyBVZzMN2oR_ z?IJ%>D&nxUs~Z@uwI<}jZ9SujxQC>Q z@cOxiWv*+{`e&v6;eBb->XD+D5DHV=fn^VL zHaf{8e2E%AW=0X8Iczg=EISL)VFx_9ZeoP5b-VVP|HFL<;Gm%Uld2u&Cc9jUaYNHo zA1*9}>@2ZAgoiLu1*>TiLG&Xqqhw$7elF&8mfx%1d`4H|x~snA{@+vnjsnnNhIjoj zgm8r6FacC)(H1a7N{_1*QAZ;hQL|V9CBkQ1!JzO6#JhOWX(;Q!lGQWkIJa zwQa@TT&8J3SvMqmhcVjOwCXdgC~EO3_l;v(*6A`)KHZp*4WLrSkPG7N*hM70GAQHB zQBIYpIW_^-zA4*KhNLQAd!XxTPY4TljpYG@hH&Ry5&00!!?{IBmxsXIDFyS0sTdOp zXAfmY!^J!S$58oW0IGz_pn4B9VFK#M!N_Fq3-uwVr*`^3)1s6LReyc^HszAwhtRla z&$x^555$_M0+mQ4|G&xyGPc*9GL&k4NSI`Xw}>Er02}TseYzv?8NIqxYaDC95#iMP z3P7JfOt}#%x{N*nMKK{4 zg1hPO8Z!>>bITUs>&o_m%W$B3MIBTv>i4ozx0b3LIU5kSZvwq2h@k6&;wQG4!!5uP z-JM|dC9J(tS8q6ti|F-*yS@hi4Dvk86rKso0!2+Y-O$VpT6#HEq(E>ZsGkeRhyiTu zF9EX+eT+)b$5@QAcm;ioog;<;0qyIeUl-b-ELmxHiJfPerXytfbS-RJFL6;Kh;S>4 z<;Q?jE-l9qF!bsAhRG#nxu$&e{sYuK@u%xlr7s4Dk{O|Ff?EIu`^tYB*-IIi(R>Bg zpPEp0V%HiYcD_;_GOXYJXs+lQGeYAzTKwjGmC<34?Lu9V$IRD)%EMQFC$M^|F z85QY|0Y|`bPS+?yvtiQ!GHK)OJ)GGG2dp~+YJ)IPV`3>EzJtoaXJ$8Fm3?`<#LN96rJzWx9tVTj`j|4M zPHxrz#z?$-9S~||XX^}^@9TdM!R?2@;37(zw}Dc(?YqP3R5D?oLWRlt_N+7;768Y_ zTO%NyqV*6iHNO_OZ9;k3SqJ{%Fu2GYC>P|1rJ!`-gbrFn@ZS+bZ=c|DgBC1cFG2Q2 z$2=tlid(b7fznL($rzvOqqiVPAjP(weyS;a^Wi;~61tL*yJe2g2b|GwP}LZeq}oNJ zy^>EOqWy)<2@e->YN{GNHKo2A!OtyE_^i(Mrn`Si)slkwh0a{R zzB$Nw?P`L>Lt?99M&Oh?mz`lBJj*)+niQN2bacPkbe!fXbYhg$;(W~h)zJT zZvocYqy9Lp7UA0lcEeGe#LI=#5cGeZKo>8lF%GoLqv=RiV#yURpqE)xxN_}EH%Wmt zz7f$(ZU^nbS60Q*lsP zhk4*BsT05oT*kE^#F=7AX;wQDp!9(nI|GrYe-^wHn}pZJ++@Vp8xzEVT6xsGzr543q-WVv*Jrcf(xCiE9< zhZVA?a_-=~Rpxek}IPpsv3g0>< zpde{i(@`;6siRm+9qJm0N?MoAm?6fSPI-hoGqkGr*7I!PB-D4DR%s~o`- z&^=lMgz@Rxy=jM`n3=%k*7BjYK=&QGKqOoSDqOk`DEu4%RQJhEOVbgE{7px50boU%!XO*$32YQ`&oGPiLCq1+ zRV_{ffJCX-v4JhPvl@@#`7^1P?oi6~3w*+0&%?Qv?}nhbv?Xfn$8L_Vvflh<^E(jIJbExNgx1B3>MO?Vp3rev-gi)&kc@A$e&2vox z6fx+dcJ{?#mQ6AH5*f%5Q74P`Ne@_ZG=45NXp4kgOz8BQECTyO_Ka;ogSOr9Z}9s8 zpn`hF{#C&6GL|eR0vmN_$*b&kAVqZ1+yil`8b3Vt>n5Kxf1d#l@c>YXypi-Cf_yJ3 z4RYZag7LlwgxfH90nz~T!MHt`F#zd%4q{f5?z>R?pF!WYe3ZEL$Cl8J+cB{z&KgMx zb`7|12#2;y(48ubFkuL->)Zw`S;edz{vs`8M@SC8J)EiAMsEUr+95?eNj$@QbEJA< z4JhRgU@de8ZF2p03dDeb_%BrJN|bIr{t2AqG>E}Ia)Z4bP~QqfIxjCz%nMAg-e6zw zmLbz6Jp)EGtD_!Rpxe!hw`=fYwNDT(?xoN5tHUz-x|bqZ(EF8|xFJP4 zhU6_!LV6MrNjjntAUWM#5&qgpO;mVf0Zvi#%MS#}dXr12V-C0OW<$VA1tdE#9I0GNC=^b>csHA|2 zJO>ghKG7&YT*hhZ?aaZOUe=s9XwRfG3=$gn$WKf;Y!;*sqh379r!zxJv2pvqYb~~c zXeXBh%piJ|U1YFCOIF~mFDC|0bDAJWz1ML2Upt`+ZtGx1w@)#w4Ni>%aC171vPa5RB3vuxk>GVTRfAQB22%e@gkDLp43Xz|S1Q zSV$G{>7(dRq1&xQI~(m!-&_lt-<63M-`f6aR|azs0L3JO_EO`_aiVTPO!Rj2=FSz014y3Ta0uk^wvpOT??#aGpOn@;d2gQO|Y zdY&KEj|0C~TU~h!4my5Z%@Hw04uW7zk$+-P8KlkK;LpE{ z4GufnJQdbyvN_&6=`3*7Hzm>t#)?T(QWG3)2W92U9}qdBQM~>`;}=k{ZaHL=!d!eY zIAy(9|Mi5txvHsD1j z^iZf^2p7|a`X98{0?OMcu>|4L7Oj}I9abMbiv(6Jtn21 z@;aD#yMJpCJ}4Dra{>MbEX6?3nnndmw#SG@;Sc=4iQW7m0d}|9^-ls?0ESy8P+Ufl zjpXgwM^lXi{q6xzX9^dV{K{>i4p=Ft5-kBk!jbjlYsT?%Gm18g>4M0*LXWSBBON%O z)~8>I+VYjqZ(7g!vF*L z4Tj5>oRYZ_>|C%+l|ZYf6aHl!%~$7Me3Qo; z%M<&tK~wEvA9-)~0JL)}aXKf)Rk2*GyOhThM#SDec$D6vEl z*d7Zxha5K^ZZB3wYEKk_M)rzDwyUot%<^#&v9A4Nds50?fkVLOIp)->!<7ANbE6d5 z?;h!&<_OB?luBi7oo@9pBW5NE4+L5kVQ&t7)JvS(XG-T459S@=NwplIU`zcjlAiauBXFiG>0F+dZ^%0!|H)OT&Qg1Cp;S;_oP8LdQ!Ea@9XE8WO=dA zK&itbPq($znCye$EB`ZuOuf1bKVdqr)!8LqC=>?;nyk_Fg3SL?t&3y}Fs}(658JGz z22Gy!Pmm*eqn$mDR!2P!;4$@tKs1L(-|t}tqm+O9MtU>0*NR|QT<2pHGh&d)rokvX52!S4F ztAD2(ftKcs(18s^y6hM9!oNl0$EO*1Xf(k^p?PhKa*l?BZq6i|a=VshUN@TH9P>bl zkPCX!cMYQRgx#M-Uh=I5^U-4$>GzCJn&d%%;S`t+FpEo#{>@Atu*@a zDg7wkK0$!`FqIGry6=p*@xJO(pq%ykZH8(|kZxsk`qZC;~*+2h$jzXQrz zieVh_B*a6)*yHm$dyOlZVOsA+8i-bb6YeojgVp5m+z&B0ZJ7xU;7wS{cEAof$(wZi zAEd(o1x6TFUoj?9#tor-ntSWbqb8r?PtiNP>SdWhT{OYtUTkHiQC4c0T2p5xO{89? zR+BFy&+jb%%GkGF80b|Ip0-PdtE}aM^no^OgZ7Nr#x*_T%r)tpTR@El^uC&^ z^o<=zT{M=UK*KuCu*^Y;f?Ol$H=A%kN&Z z%;^<4Pmy1lXptmH^X)Bo(8oLbMtP9tT}zPSCYKjEpwM8zo+OSWT40$42>Ok(lMj4` zE07Df2vCW+^^7CASc)bp9c++mz&2Ii2L7w+Q=bS3SP0|k;o2X~KZT|_KQ-%beb$mM zd>b4t%4t(jdWim)K}u|M+-Nb%?e)hCHOO4!ME^(kZQmuvu0B`Rlb<&^LYET~F(X3T zNgC=)TA{3v|Hz3$sFeGV92OoNt|6Uw-0BcrR7lu3BmHS`4#Zec#537Y-cKrC1u!kWh-Y`z#Ha-;|MRS3ro}Bu zJYn_Q$m^8Fv+t<%beUKOgQy5nrXGW>Gn%Lkqc<8MN~ubX)pBKCm6TXI z2&ZdXgKR2sx7_!WR2LnQ0i>65;qJaF3EmtdxK_?=jxj^h%d3#LP(M0Rgmez^#?{Mi@a>;{d>{_X

  • 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�`tSO4@%UP?qDf#yz(>C#g0{RJH3IY$q%6AzhI19oX9~R)waN z@-++oT{;9o5TIXVs4my0U-YUB=;&iUts%-8aF!l5x#>S6Ts>P4SRHT{niT<-|uN_#^K!`ce?LHMrx?P?#FYO5A zTG|$1XmA`Klh4T#Uri#}cn)YIPJL6V@|Zg`No&*pduQ76by4Cc=QHK*l>V&7v`P6K|RP5=r_W^9> zvM&_ohObG_t=5={-+1Gjj{EgBG>lE&cvc1A8r)P>;^_Xzw^N~vD8`lAXq7dM!uAi$ zv&JNouLf!b++L&Yw>|#-d(NLIk}}mmJ5_9;l76{qQMWMmSk%oUIJ{WEeLlT=GW1ZI zSQvvOxA1quqDaob^Cf=V=4|=aVJcbb_QkIJ@Yu?VXC-&`4{;xjU@MIYTt z$-_>&5w3!Uom1oP&@bxtO2{o&d2@$c)>OQ+BNAq&XbNfF3~H89sXvm zsI-Z>X)2(l-<~a=LO2LmSR*{uAt=Owl3@#M;f02-y|1>lDBa$)&qt6D zu}qh!d{}fI&E!pmYJ=QWQ3U;(RzT?AISAkyF!nvB1!+(DTL;2EKv%HcjVYRx>C&zT zQmnR7ghJ@Wj;@XtG+2IKs_znT36bABfvZ!b)cUxwyZJ@!3=|dumruqAal3R;h?HvedhxNBABg+1)CdC{dt7toC9D zV}0+f+jsnac!@k)~9H_9!&njV$9M?TCe+5Hn02?@JCsG=G}hq zeJ)E;nw*S&qdFwte=jW(e}zG0bg!yD*jWsVR2@XQdU zQ}Qyu`WsGsug~~@s>nlZ-6Y-Z^0c$#JXn~x1)?6)eO7nNqf+D{c!>|GC#wPC#%*qe zip_^a-X~A&aBA1%{;di>ACT&HOH+q@uDZh(=x8ztA}W26PAHsOUA9r`_fOiHo&_u& zT29hdwvsz?ca<|sdhqK8Q~Z|&7ITe#$?00Ih8L4!$y<&3jJVbB-UK%t)~KByq+M*+ zm;CiiRrc9nZ)q_>_TCP6&l+#$bs=STS@kJpdN>m-@x1x9T_U?NB{gNyDb8_NkLq@x z$86Q5D6DNrV{la4p#ZO5qcu-P6xYJkVQclJ|0xXh#|ac(j)J)ZOSIYC3#3n7FT1OV z6FY&h#BC|4B7FP%w-|=!V_qNwwc!VG4^V*kgM(~6yG7psfZ-sd)r>$O(#ZLic8bfA z2xRqtNX55Y1at`_x&LK62nXOl2hIny?R6jM_$w;{*T7jP8z9UqBSFE4g_8Wlk5xVT zB6ZI+un%J}Yns#b3X2NTQ3A-k$+@%9SSXg6h4hgHI7eUZ z>5tn@c`VZO-|G1)z~fWcP8xYjr{f#6C*VHc%5W08n^_P(+oIXcHOCmb_A`iwGOOX} zrxM+;s$G>|c|@f!=3mq2C+(e^8uK4F;dt+qYq?E4b__Nh2p%_f>ks8*^1jzM3G{ai zCTUj+CaHCjAV9qgfgRNxuE@_izkGMATrDAZ36M-Moo^& zjs%a<(_a-K+Ka!QtppE$gZgaBv3T z2AqFOh2iT-qRGB8#KNm(sBDHj%sv$~&UO^pI^~1JnQ|?0N43BdDi(@5{1@R$Rx$}# zbtmaZ>4m#~AO2d>(Xdf+4$|=NdjDNMZe4q9zZuJJxp`c5SAJ&H;#6;6j6D7QQQr8p zKwm{^HLQiz|5JZs@w&AehVXT-PntVtvVHWdH9Y;wr-HAVmbrI*bJ5u@?J#I9c648# z$P{6N(_|UA8qIh|doSsAzCUBp{rLUMm$s~hliYXB7g6{QLv37c<0lRtVSgmrZ|PMx zOx;Rtn^GV**D)! zu}ebV>@R{PJk4jJlIza3zkln#%H#wQblT5A5TvS9)#fl)p|%7<`PB6EBKP)e4G8@= zfFz^ybfeqpOWmhW2n|mM{q>xV-?_4SH#+*LP5!&lVX8*)H_g^vZVIB~ z_>Zim)%#gUH~iI7RC4Q1rDR5tC~XEg=JZ}|Q?K63|t-Wv3Oi2Rk2%L$@zMGc`i@m51lbqSdTspEIaxR>f zGb<*h$9Pl3l*buvdn1ExMQfEQ!WXoxgz@FlB5W!5y9)d_#g|q2kG^SfuQ#H#2Cb8t z4>6=&zSq0AC;ueA+dVQewZ0KI7NFT57q@?-nKjZ?wi!6rWXAC6P z;}30BW4AV`_d3qqNx6^Ovt0*un-%T@Do%XWt2@Dof!~KbPB>LZKXm*gN$-DY-d&Gb zYIlD)oP<+Z@Ljyt$|)_Qq4#t7itrUrYHI2umhHQAH!()u;s#uih?#Hw4b$33sl(6&pErZoTwX5uent zA_Yfmk3cG<{b$4HsRybXERM_H3V$(CQyo9!*&@Q_yY`fDKd(4QjVh7-NL%L8>%D3v z#QwOxh=u%N_}fAT9Or;M!{IBxYSzSnr05t;b4S+k7zBF$=G#$6MQ_^B<#()(9n!Gn zn=i>HDOYvtDPBCMt-%LK>UPwYB$*f3J+Xd{R79icwfP`Opepj)lD5%%Awxqf-mYz| z5A(49`*HNr=>275J!7fNYup*X(Ov{t@w{PbtOLqFS|pg!l{!fA6iLx`CRny-&}r@a|S+sak^We z?>}4re1Bo@6&a0w!yh1 zcEZ$*jDwnT5SC`2eN)@p)ARiguk&&QNHAT%AwCtUU#KvAcl&Ui_{hECW*!nmu^xax z6o9%C$ig2=L4ndt2%8&ME<3wfT!Ku$l#^p6&e!5z=c>r%dq{dLRb_PNN;Ts)J?KX{=5&}fCK1op@ThG6HmrTc$ zJR;K6b6J8zx9V5GbBQ{)OqnGrFW-m~{Kl=JHfFAAkB=8G24$lCqpvy%eB1kXu;h!c z{#N^shbIbd2lxA!O*Ug~tMi|SUA(cyEBWe-o%s{;?e)=^oy&)>=)YDhLT2ccwLAMj zdF$cX_FE<9G9H1mt{V%!2LC|)S;XCzUk4dP&Yr@a1p+ttwOF+ToI^i%;}#LY4=q6v zCuTk?&9ArEwjx9kpV6jK+IP1QZ>+>!Nb$&I++y`fp5y(BN{*zi;sau@^oo}#A7N*> z4OtIwZa@%ggkR>J=&)n$(7&Lb@+yt~?Bb(>vBeaEz|sW5<J z_|Dj9wfu%CnMi2Ol!nJANvxIi&tCm+qZ9J6%?kU1`NSD zwuk~tZ$i8Do!gBFY-`(BaP8Q<6MIF}k+Wql3_h~i^e@*m;84FsqhDH;h;ib7%0_Is z9AVGk@M-LMctlSNtQXx`+4}5C?N@Ui##WPQ>t0;GM0BDuTC=VqS-j#CO8!tel(#d) zBjQDH#cUVETe_Vg>hi}zA7ZQnzZOx-EFk%!2@6((4U0ENmYY||Y>B%!{bc6%N9L!6 z7|xhTmiGMLcHBKH#)*4qV_Pk5fp0_P@~?-S;{Sa#}$A}YaWm$ihhYamv@Fl|#-$9tj z%5qe-zX8h+N2*kY_EqRopV-EJEh+k(L|km-G+o!5RLe=o`?QJp%Hqg8df^Vpo@eGv zDG+aL>UE0u`(3q1*Z&H$AAWG5EDOZ3Ixq}A6TNF`HyEX7GAvk@=Wn&$IqQCTf28wb zT0`?%neLpAbMG|$!$Jby@AB!R*jkev^n#7r$lo%9Xh*p8@6#oSwbdS)xL)-I%^y~7 z;j*?4>zWB)QvIn?6k^AoQ@0=(0j1jd*d}QBOsb#jsgyoUTc#>{U2I9hfm>sf)_CpA z?`EbYpbJ#f*Z%^#x=KBtOnE0j=-|Sfw;4!jlCQK?sXOzcTTD|m0J+CyHlTy?9~h#O z@99qna1juK8zsb08oy6d+V)s{no-?>|1uNR0HTA9`p@IS0 z2r*99#c6g@MOO^OySO)NSF59mb?*!CaTnoVSdZH?)?w9k-u8qo#cvMXp z^=7s0&7U@a_(XMb8||v1B_| zxc#}`kd=OQ=XukWNQ_pKc~ILFNWw-PGyw7b203A)=Y5Us@JsN1^xt5Hp`U9V9Ao3F z4VjZ&bD~~F3kyVIgPfKPvYo5lfw0-sjGFWEa2g^{8t*?|LLW4EGox&4Um@3D8ShwR zF7_=MIV)zo%v4Fhi{|t2epJr~N2-V3t>gw>?O~*cmm<&() zp6NUTZkE%cs&*`}^eTM!vo8f~@`r?muH2V?51}>an)vwtISC}8UD*G4kt3J1;ZDpE zL)JqO_{7bi5G7|uP%7r2M)DSXiX6+Cl4FSe2xF*unobcAZg8bxWIs&_pCik0LD+ ziZm$#0!9c;K>~;5+z!Kkr@Z z=FeFxYp;Fw*=L@4W@ew6=^&+LWpOlr0dho)mKG*}vg3AuF-)tYqvHwGMlE+7zv?(% zNdvfnEX^$~ujAdkZ||F*W@k|=wjYjFyR8n9|*q*5N1_{Y3V%~RYkV7)2JKF=*^W=zZo@of2# zUCOAX#s%*i={ZlfHg1(K4&K^{k}veo2!w6U$z0}2pMQBRDL5yXzMho&yVkxoTHr)M zU8Mc#;mRMX#EPLtrc(2Byp;2Ko8;1B!&Tflg8LqLX%||txSxqDt*x3IXWy25e{1s( zr-l?Ox14Zih<25=vZ_deW{M=dPE03kckBS{vQV6T^h9RQ+8WjA~LF}v}%AHgy`8InAnHh`%`;qB4H@TA2Tr) zackq7>jD}4qrKX<1fVh)$Qhl;dvSi3Y?f3=pNrb%4^Q%cP>W48KVsG1+D*9?SH4(L z7s{)6i5k({`uU#*;2WmTHp`JUVjAXUq@p46??jjFu>A7y%4io3^p9)2H|(|yb1T29 zJrz$0*x2X+F;qO=$=o8rgGe*aA7;JeDTfh1))I1+C_EpYuB4rn<~} zCWCQr@3Kg5O<8q4+i-lr#xWXOS$s)%WC2R3`BQRr-DHqS)q^mUNls71>@qOzUuk^I4X5)$;UyQ{xgmzcfnEo_)^i`>7C}($aFoly@*P@?U2#y^_!Z-^BI3@o_pCyIk?MG9Xk@Tu}IAu@crZnYOaE^P?vW8qOXiWzfwispOp6*m^yDg7> zeP-uLPtW*5Jn^4ROQO_ohp@*DSM~_;oX@^eKj(UH8I+0-V%SkmP9y>ak%jG2{W4@! zC0XwRtvK3%wsBs=A8OZu1EdO{J*V6&-yl>#{#Xm3N}DRWS^@6`2`$%Z+Ul70kG{eP z4nT%z@KH{RKHZRw1qYWGC9NgklBu=n$!2ZlI{Md=vCQ!oMB2^6*RXfv{p2*}3p;eq znc{YBVZ250*vK`8?6D_5ZmBgbU2UR&Db2-yWa;ROGkJ~x-;~AOIAX^q;x1Y1`dg$I z)CJ2rMb#Lyv;{seYJ+o&b-FQ1ZLI~`A5)YA;$Y^T%@Q(1sw^Mm(8BCwGH%rF`x1$D zeMHQ5!tMitjscv>L%87GM@8e+x`b9u*^MH5h!iW@yt$L-Y;xQ)+(Fr%g@1c&RvIr4N2qP}ayi=qAl_c;tx<@OpI zc|>xifS%HVz*U^A!FIw0)xs`)HpjB>WcS>g5^HJj~ za*83ysXhGK3ufPAM$y?uQk5%Hl3_Bc3Hj8J+8#Wr>fe!Lcq)_cguu$0&In?}jLsXX zt@&RYDsP@I4P3RSB)7W>?F%iIQQmq7@n z;rLo#k7)-q`uQkp|Jv-}4JL^A!I!05T%{~Ef z4YgO>fU&6@$|u3xyngqBYPlq@SVBX`jgG7$x|wb_r<2<<*QJI z#!F+mkh68Kvl|5!Ko*+3@0Py9Y z^!?jg0;`!meap%Xdl|2ufx(hl!YEYum5?ic8LQ|WEGTXJ27 zB?FXP5TmPeMt%uHf*}Yj+rE$oA>GM1t|OW$ZRagqk*G5e zWnw?MqNvD?#bR+%lsYclR7+D6vK~0&t``=f2N2R^C&(8#VW*CuI|JrnBpghD*)qN9 zhl8x*wAfUFKdIZKTOt2(k`V@d$hs>KAb+DSqmKcyoTsqKvAJ=h@93t4V9q^PaFvH} zGm$Q3=b|iQ?T`C-GC!-ub&BR45#SD)R0J^0VG8Il&dqN6c%G%hRZ_HQ;LplaYuW|Q z)%?rIhU|*m+*}2h`Orw~uAUwmgqL+Rb@;6@n(9WNYtE=Qzj@#JalX@;ctHF^N{8%8 z#|+>|p!KOqWL(uh@J2j1B-FHoMXA(Ej_VUs3s-2LYH!Q6pZ23!NSvDrIG4LA>V*2v z(>#Qe;Z25$Mehj7BFzzajKH06Z6BU<+H6L>X@X?u9oV{XP1GbnNgR)hh2OCZrx=K~a5)h~$l;5Z1~w$@9o z$VCwUNE!{9$)kWPcxRCfI7k^i&Pc%4^y!#w3JufhB^aHmw56MPo1*Vx5RavJF@ABz zijl_AB%m;wp0}v85wE&h_l@kj@ycs(B;+BK=bfFpn(&KNaT~> z1_`+;A)Nuep;Fdh?XN}EyNn;42UbOXzqFdyLy=TKZ+OYrRwa1=A1mKi?dGN~8D1Fh zdlY*}(vv9oF~JREHrLP*Ows-ZqLKy(42WV-5pV*|al{9cW`IY5UffL`V{y0u0YMMK>)iwgQcMqEhvT#a)lj%_Hd#R{W;P<$jEd=6vKp<1qciX zOJ%-@z7FL&6lTE^#Y@%CZ9aqiyh9Z-3ySLZ%Zcy3=%CkKO)q@S%-bjO0&_$yop#Fd z#6hn7-{qL%sZKh1FEih~S7LW>U|+C8ImgrigclbswCNJ1^ncmmMB2jIZ?pcp9wPvu zJw{~_l-sB4SuGquziK$cZn9xGR-gupw5v|6eJSrF!uI>Y?XQiO<|n+EW3kUabfFAf zJ}O-U58Kbp|AQ~TU<86N+BlOPKJCX~U17Bj=vr){J2Fx=N7ls^w=QkV;|a1MGRptZb2R|ATS20d2Fji7e%z){_8b=PMKt>ea7Ykr}HNvcns} z22MZ|M@8VFIG*3DI+HX6dCly`(u>0%ucIv}tj0lR)?{6N>2u5okJ4HPT51-IXq351 z{ZSeI>AtPuYd_w+7-v+>ezo+f%e!+#D%Q`bbcBebgl>Es>{%XKqug1F>)m6vjuC#J zMe{eQvfm)!2x>{KbEFi^C|EkdKzvuUDS4j$G_(bT8Pp&TN|H=Lq`?G3%~(*Vqm2NO zK|ZRXtt)eSy#poGcm7jQ)wS5i&a%w;?*F1oi4m+;;GQHVas(g^M0l5WQDDp?Cr_4p z`0^pz%s=B5n?tCL%|MejiH-bDd0N{q&)j4@Gcm~zOv~!*!R{NNB?j)9V_jKMiP?3B zKoq=g&PWT4g+AyyN`jvaA>>r0bqTWG@jhD-l{An4?Uvj8=6FTo3x5SN8lDzRr4r)c zlrf`*dLCFtrWgQV2c(!u8nZ++@8Vm4A>^!S%vd7j%E?*igXIF}u@nWH0JQ!96dC=Z zf5)}gNIxwF#W=5}_WzF}a{4F(jAGO0AwWo1U=Y_8{kqLJbP>V!p$%?kq4%mpk(RnH zd_a%{sz%j1Q&{%WKrj=7-e_MBr$Wm-VNbfVeBdY02xVs2oi%E*^w0UF88LzCNvJir za88!R5k+Bt_1aEg>&w)&;g4?m7r zcFIrwCNur&&M*-VJqEw)_q2uUvB!fi?jT#Yo0}{3wbR+NfWd+04D` z03v<1tv0b{(^G-v^(k~Valff^@fP(Tkoc>Hl!U>T**xOe9dl)`4U&4pvFWL8#)X)| zyb30tuRZJ*xnH#Qq5SqaL40W;eX}>|qcg|!9#SF^5@LUe4)ExsTYlMs1OF<4S9mG} zvY<>nZ_^M}J{+$P5$U{p1vvJ_x_XDfpBvt*BM3#gx0Slk3bfZpyq59|>30fq0VZ-| zhdijbr-21p8-E3|rq5l>imZD4(_D|zeX^tJE%wNc`#q*mQCx;#FYq%0A=Dq?rceBf zd_HjP|Ol;hb1LAcqj3jSs%9PVfBoQ(r~m)} diff --git a/layout/base/gtest/TestAccessibleCaretEventHub.cpp b/layout/base/gtest/TestAccessibleCaretEventHub.cpp index fe7ca4cbcb1..d655a6f6b2f 100644 --- a/layout/base/gtest/TestAccessibleCaretEventHub.cpp +++ b/layout/base/gtest/TestAccessibleCaretEventHub.cpp @@ -60,6 +60,7 @@ public: using AccessibleCaretEventHub::PressNoCaretState; using AccessibleCaretEventHub::ScrollState; using AccessibleCaretEventHub::PostScrollState; + using AccessibleCaretEventHub::LongTapState; using AccessibleCaretEventHub::FireScrollEnd; explicit MockAccessibleCaretEventHub() @@ -461,7 +462,7 @@ AccessibleCaretEventHubTester::TestLongTapWithSelectWordSuccessful( nsEventStatus_eIgnore); HandleEventAndCheckState(CreateLongTapEvent(0, 0), - MockAccessibleCaretEventHub::NoActionState(), + MockAccessibleCaretEventHub::LongTapState(), nsEventStatus_eConsumeNoDefault); HandleEventAndCheckState(aReleaseEventCreator(0, 0), @@ -502,7 +503,7 @@ AccessibleCaretEventHubTester::TestLongTapWithSelectWordFailed( nsEventStatus_eIgnore); HandleEventAndCheckState(CreateLongTapEvent(0, 0), - MockAccessibleCaretEventHub::NoActionState(), + MockAccessibleCaretEventHub::LongTapState(), nsEventStatus_eIgnore); HandleEventAndCheckState(aReleaseEventCreator(0, 0), From ff90780c49a4418913e55f19742fce54757abe5b Mon Sep 17 00:00:00 2001 From: Alphan Chen Date: Tue, 26 Jan 2016 17:11:54 +0800 Subject: [PATCH 021/218] Bug 858827 - [Geolocation] Add a handling for getCurrentLocation when timeout is zero. r=jdm Follow W3C spec, Error callback should be called when timeout is zero and there's no cached position for getCurrentLocation. --- dom/geolocation/nsGeolocation.cpp | 7 +++ dom/tests/mochitest/geolocation/mochitest.ini | 3 +- .../geolocation/test_timeoutCurrent.html | 56 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 dom/tests/mochitest/geolocation/test_timeoutCurrent.html diff --git a/dom/geolocation/nsGeolocation.cpp b/dom/geolocation/nsGeolocation.cpp index dace3d3b3fd..7bb7c9cfdae 100644 --- a/dom/geolocation/nsGeolocation.cpp +++ b/dom/geolocation/nsGeolocation.cpp @@ -530,6 +530,13 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices) // will now be owned by the RequestSendLocationEvent Update(lastPosition.position); } else { + // if it is not a watch request and timeout is 0, + // invoke the errorCallback (if present) with TIMEOUT code + if (mOptions && mOptions->mTimeout == 0 && !mIsWatchPositionRequest) { + NotifyError(nsIDOMGeoPositionError::TIMEOUT); + return NS_OK; + } + // Kick off the geo device, if it isn't already running nsresult rv = gs->StartDevice(GetPrincipal()); diff --git a/dom/tests/mochitest/geolocation/mochitest.ini b/dom/tests/mochitest/geolocation/mochitest.ini index b41eb8d1692..e70789d24e2 100644 --- a/dom/tests/mochitest/geolocation/mochitest.ini +++ b/dom/tests/mochitest/geolocation/mochitest.ini @@ -44,9 +44,10 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #mozSettings is unde skip-if = buildapp == 'b2g' [test_shutdown.html] skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT +[test_timeoutCurrent.html] [test_timerRestartWatch.html] skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #TIMED_OUT [test_windowClose.html] skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT [test_worseAccuracyDoesNotBlockCallback.html] -skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT \ No newline at end of file +skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT diff --git a/dom/tests/mochitest/geolocation/test_timeoutCurrent.html b/dom/tests/mochitest/geolocation/test_timeoutCurrent.html new file mode 100644 index 00000000000..af6cab328fa --- /dev/null +++ b/dom/tests/mochitest/geolocation/test_timeoutCurrent.html @@ -0,0 +1,56 @@ + + + + + Test for timeout option + + + + + + +Mozilla Bug 858827 +

    + +
    +
    +
    + + + From 2974c51f6e553ec4ada55015d68f2446683a2ca8 Mon Sep 17 00:00:00 2001 From: dimi Date: Mon, 25 Jan 2016 14:18:29 +0800 Subject: [PATCH 022/218] Bug 1188822 - Make service-workers/service-worker/fetch-request-resources.https.html pass. r=bkelly --- dom/base/nsScriptLoader.cpp | 4 +- dom/fetch/InternalRequest.cpp | 45 +++++++++ dom/fetch/InternalRequest.h | 3 + dom/workers/ServiceWorkerPrivate.cpp | 10 +- .../fetch-request-css-images.https.html.ini | 5 + .../fetch-request-resources.https.html.ini | 5 - .../fetch-request-css-images.https.html | 99 +++++++++++++++++++ .../fetch-request-resources.https.html | 60 +++-------- .../fetch-request-resources-iframe.https.html | 2 +- .../fetch-request-xhr-iframe.https.html | 2 +- 10 files changed, 173 insertions(+), 62 deletions(-) create mode 100644 testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-css-images.https.html.ini delete mode 100644 testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-resources.https.html.ini create mode 100644 testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-css-images.https.html diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp index 8e99accce75..e0555585e3a 100644 --- a/dom/base/nsScriptLoader.cpp +++ b/dom/base/nsScriptLoader.cpp @@ -294,7 +294,9 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType, aRequest->mCORSMode == CORS_NONE ? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL : nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS; - if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) { + if (aRequest->mCORSMode == CORS_ANONYMOUS) { + securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN; + } else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) { securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE; } securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME; diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp index 07c9fc0b13e..01fe39f8bf0 100644 --- a/dom/fetch/InternalRequest.cpp +++ b/dom/fetch/InternalRequest.cpp @@ -324,5 +324,50 @@ InternalRequest::MapChannelToRequestMode(nsIChannel* aChannel) return static_cast(corsMode); } +// static +RequestCredentials +InternalRequest::MapChannelToRequestCredentials(nsIChannel* aChannel) +{ + MOZ_ASSERT(aChannel); + + nsCOMPtr loadInfo; + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aChannel->GetLoadInfo(getter_AddRefs(loadInfo)))); + + uint32_t securityMode; + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSecurityMode(&securityMode))); + + // TODO: Remove following code after stylesheet and image support cookie policy + if (securityMode == nsILoadInfo::SEC_NORMAL) { + uint32_t loadFlags; + aChannel->GetLoadFlags(&loadFlags); + + if (loadFlags & nsIRequest::LOAD_ANONYMOUS) { + return RequestCredentials::Omit; + } else { + bool includeCrossOrigin; + nsCOMPtr internalChannel = do_QueryInterface(aChannel); + + internalChannel->GetCorsIncludeCredentials(&includeCrossOrigin); + if (includeCrossOrigin) { + return RequestCredentials::Include; + } + } + return RequestCredentials::Same_origin; + } + + uint32_t cookiePolicy = loadInfo->GetCookiePolicy(); + + if (cookiePolicy == nsILoadInfo::SEC_COOKIES_INCLUDE) { + return RequestCredentials::Include; + } else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_OMIT) { + return RequestCredentials::Omit; + } else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) { + return RequestCredentials::Same_origin; + } + + MOZ_ASSERT_UNREACHABLE("Unexpected cookie policy!"); + return RequestCredentials::Same_origin; +} + } // namespace dom } // namespace mozilla diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h index a000a89ab04..644f55b89e5 100644 --- a/dom/fetch/InternalRequest.h +++ b/dom/fetch/InternalRequest.h @@ -406,6 +406,9 @@ public: static RequestMode MapChannelToRequestMode(nsIChannel* aChannel); + static RequestCredentials + MapChannelToRequestCredentials(nsIChannel* aChannel); + private: // Does not copy mBodyStream. Use fallible Clone() for complete copy. explicit InternalRequest(const InternalRequest& aOther); diff --git a/dom/workers/ServiceWorkerPrivate.cpp b/dom/workers/ServiceWorkerPrivate.cpp index fbc3d3de5c4..4c5fc3966d6 100644 --- a/dom/workers/ServiceWorkerPrivate.cpp +++ b/dom/workers/ServiceWorkerPrivate.cpp @@ -1094,15 +1094,7 @@ public: internalChannel->GetRedirectMode(&redirectMode); mRequestRedirect = static_cast(redirectMode); - if (loadFlags & nsIRequest::LOAD_ANONYMOUS) { - mRequestCredentials = RequestCredentials::Omit; - } else { - bool includeCrossOrigin; - internalChannel->GetCorsIncludeCredentials(&includeCrossOrigin); - if (includeCrossOrigin) { - mRequestCredentials = RequestCredentials::Include; - } - } + mRequestCredentials = InternalRequest::MapChannelToRequestCredentials(channel); rv = httpChannel->VisitNonDefaultRequestHeaders(this); NS_ENSURE_SUCCESS(rv, rv); diff --git a/testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-css-images.https.html.ini b/testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-css-images.https.html.ini new file mode 100644 index 00000000000..110a928078b --- /dev/null +++ b/testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-css-images.https.html.ini @@ -0,0 +1,5 @@ +[fetch-request-css-images.https.html] + type: testharness + [Verify FetchEvent for css images.] + expected: FAIL + diff --git a/testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-resources.https.html.ini b/testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-resources.https.html.ini deleted file mode 100644 index 162d1bf2090..00000000000 --- a/testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-resources.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[fetch-request-resources.https.html] - type: testharness - [Verify FetchEvent for resources.] - expected: FAIL - diff --git a/testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-css-images.https.html b/testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-css-images.https.html new file mode 100644 index 00000000000..2bfd9c4193f --- /dev/null +++ b/testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-css-images.https.html @@ -0,0 +1,99 @@ + +Service Worker: FetchEvent for css image + + + + + diff --git a/testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-resources.https.html b/testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-resources.https.html index 03ed2b25c87..6affec97619 100644 --- a/testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-resources.https.html +++ b/testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-resources.https.html @@ -58,30 +58,6 @@ function font_face_test(frame, url, expexted_mode, expected_credentials) { return frame.contentWindow.load_font(actual_url); } -function css_image_test(frame, url, type, expexted_mode, - expected_credentials) { - var actual_url = url + (++url_count); - expected_results[actual_url] = { - url: actual_url, - mode: expexted_mode, - credentials: expected_credentials, - message: 'CSSImage load (url:' + actual_url + ' type:' + type + ')' - }; - return frame.contentWindow.load_css_image(actual_url, type); -} - -function css_image_set_test(frame, url, type, expexted_mode, - expected_credentials) { - var actual_url = url + (++url_count); - expected_results[actual_url] = { - url: actual_url, - mode: expexted_mode, - credentials: expected_credentials, - message: 'CSSImageSet load (url:' + actual_url + ' type:' + type + ')' - }; - return frame.contentWindow.load_css_image_set(actual_url, type); -} - async_test(function(t) { var SCOPE = 'resources/fetch-request-resources-iframe.https.html'; var SCRIPT = 'resources/fetch-request-resources-worker.js'; @@ -132,40 +108,34 @@ async_test(function(t) { .then(function() { return with_iframe(SCOPE); }) .then(function(f) { frame = f; - image_test(f, LOCAL_URL, '', 'no-cors', 'same-origin'); - image_test(f, LOCAL_URL, 'anonymous', 'cors', 'omit'); + + // TODO: Disable 'no-cors' tests for image and stylesheet until + // AsyncOpen2 and cookie policy is supported. + // image_test(f, LOCAL_URL, '', 'no-cors', 'include'); + // image_test(f, REMOTE_URL, '', 'no-cors', 'include'); + // css_test(f, LOCAL_URL, '', 'no-cors', 'include'); + // css_test(f, REMOTE_URL, '', 'no-cors', 'include'); + + image_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin'); image_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include'); - image_test(f, REMOTE_URL, '', 'no-cors', 'same-origin'); image_test(f, REMOTE_URL, 'anonymous', 'cors', 'omit'); image_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include'); - script_test(f, LOCAL_URL, '', 'no-cors', 'same-origin'); - script_test(f, LOCAL_URL, 'anonymous', 'cors', 'omit'); + script_test(f, LOCAL_URL, '', 'no-cors', 'include'); + script_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin'); script_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include'); - script_test(f, REMOTE_URL, '', 'no-cors', 'same-origin'); - script_test(f, REMOTE_URL, 'anonymous', 'cors', 'omit'); + script_test(f, REMOTE_URL, '', 'no-cors', 'include'); + script_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin'); script_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include'); - css_test(f, LOCAL_URL, '', 'no-cors', 'same-origin'); - css_test(f, LOCAL_URL, 'anonymous', 'cors', 'omit'); + css_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin'); css_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include'); - css_test(f, REMOTE_URL, '', 'no-cors', 'same-origin'); css_test(f, REMOTE_URL, 'anonymous', 'cors', 'omit'); css_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include'); - font_face_test(f, LOCAL_URL, 'no-cors', 'same-origin'); + font_face_test(f, LOCAL_URL, 'cors', 'same-origin'); font_face_test(f, REMOTE_URL, 'cors', 'omit'); - css_image_test(f, LOCAL_URL, 'backgroundImage', 'no-cors', 'same-origin'); - css_image_test(f, REMOTE_URL, 'backgroundImage', 'no-cors', 'same-origin'); - css_image_test(f, LOCAL_URL, 'shapeOutside', 'cors', 'omit'); - css_image_test(f, REMOTE_URL, 'shapeOutside', 'cors', 'omit'); - - css_image_set_test(f, LOCAL_URL, 'backgroundImage', 'no-cors', 'same-origin'); - css_image_set_test(f, REMOTE_URL, 'backgroundImage', 'no-cors', 'same-origin'); - css_image_set_test(f, LOCAL_URL, 'shapeOutside', 'cors', 'omit'); - css_image_set_test(f, REMOTE_URL, 'shapeOutside', 'cors', 'omit'); - }) .catch(unreached_rejection(t)); }, 'Verify FetchEvent for resources.'); diff --git a/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html b/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html index addb3a4a7ce..cadbff45cae 100644 --- a/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html +++ b/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html @@ -31,7 +31,7 @@ function load_css(url, cross_origin) { } function load_font(url) { - var fontFace = new FontFace(url, 'url(' + url + ')'); + var fontFace = new FontFace('test', 'url(' + url + ')'); fontFace.load(); } diff --git a/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html b/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html index d11d2be734a..ec8f54bd6c0 100644 --- a/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html +++ b/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html @@ -137,7 +137,7 @@ function mode_credentials_test() { }) .then(function(response){ assert_equals(response.mode, 'cors'); - assert_equals(response.credentials, 'omit'); + assert_equals(response.credentials, 'same-origin'); return xhr_send(host_info['HTTPS_REMOTE_ORIGIN'], 'GET', '', true); }) .then(function(response){ From 8e563e1a4606bd883f4608f5bbb2c50145b66222 Mon Sep 17 00:00:00 2001 From: Guang-De Lin Date: Wed, 27 Jan 2016 14:46:52 +0800 Subject: [PATCH 023/218] Bug 1229936 - Enable mse mp4 mochitests on linux. r=jya --- dom/media/mediasource/test/mochitest.ini | 50 ++++++++++++------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/dom/media/mediasource/test/mochitest.ini b/dom/media/mediasource/test/mochitest.ini index f4d21ee2430..8a15e1cfc5f 100644 --- a/dom/media/mediasource/test/mochitest.ini +++ b/dom/media/mediasource/test/mochitest.ini @@ -36,75 +36,75 @@ support-files = [test_BufferedSeek.html] [test_BufferedSeek_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_BufferingWait.html] skip-if = toolkit == 'android' #timeout android bug 1199531 [test_BufferingWait_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_DrainOnMissingData_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_EndOfStream.html] skip-if = (true || toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet only bug 1101187 and bug 1182946 [test_EndOfStream_mp4.html] -skip-if = (toolkit == 'android' || buildapp == 'mulet') || ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android' || buildapp == 'mulet')) # Not supported on xp and android 2.3 [test_DurationUpdated.html] [test_DurationUpdated_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_FrameSelection.html] [test_HaveMetadataUnbufferedSeek.html] [test_HaveMetadataUnbufferedSeek_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_LoadedDataFired_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_LoadedMetadataFired.html] [test_LoadedMetadataFired_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_MediaSource.html] [test_MediaSource_memory_reporting.html] [test_MediaSource_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_MediaSource_disabled.html] [test_MultipleInitSegments.html] [test_MultipleInitSegments_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_PlayEvents.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SeekableAfterEndOfStream.html] [test_SeekableAfterEndOfStream_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SeekableAfterEndOfStreamSplit.html] [test_SeekableAfterEndOfStreamSplit_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SeekableBeforeEndOfStream.html] [test_SeekableBeforeEndOfStream_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SeekableBeforeEndOfStreamSplit.html] [test_SeekableBeforeEndOfStreamSplit_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SeekNoData_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SeekedEvent_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SeekTwice_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_Sequence_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SetModeThrows.html] [test_SplitAppendDelay.html] [test_SplitAppendDelay_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_SplitAppend.html] [test_SplitAppend_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_TimestampOffset_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_TruncatedDuration.html] [test_TruncatedDuration_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_WaitingOnMissingData.html] skip-if = true # Disabled due to bug 1124493 and friends. WebM MSE is deprioritized. [test_WaitingOnMissingData_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 [test_WaitingToEndedTransition_mp4.html] -skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+ +skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3 From 1c640ed5716029c992620e301ccbecb4ce473f26 Mon Sep 17 00:00:00 2001 From: Cykesiopka Date: Tue, 26 Jan 2016 20:23:00 +0100 Subject: [PATCH 024/218] Bug 1232582 - Sort PSM xpcshell.ini and fix --tag psm to actually run all tests. r=keeler --- security/manager/ssl/tests/unit/xpcshell.ini | 201 +++++++++---------- 1 file changed, 96 insertions(+), 105 deletions(-) diff --git a/security/manager/ssl/tests/unit/xpcshell.ini b/security/manager/ssl/tests/unit/xpcshell.ini index 1afe2efc6eb..3fa90211e95 100644 --- a/security/manager/ssl/tests/unit/xpcshell.ini +++ b/security/manager/ssl/tests/unit/xpcshell.ini @@ -4,97 +4,38 @@ tail = tags = psm support-files = ocsp_common/** + test_cert_eku/** + test_cert_embedded_null/** test_cert_keyUsage/** - test_signed_apps/** - tlsserver/** + test_cert_sha1/** test_cert_signatures/** + test_cert_trust/** + test_cert_version/** test_certviewer_invalid_oids/** test_ev_certs/** test_getchain/** test_intermediate_basic_usage_constraints/** - test_name_constraints/** - test_cert_sha1/** - test_cert_trust/** - test_cert_version/** - test_cert_eku/** - test_cert_embedded_null/** - test_ocsp_url/** - test_ocsp_fetch_method/** test_keysize/** test_keysize_ev/** - test_pinning_dynamic/** + test_name_constraints/** + test_ocsp_fetch_method/** + test_ocsp_url/** test_onecrl/** + test_pinning_dynamic/** + test_signed_apps/** test_validity/** + tlsserver/** -[test_datasignatureverifier.js] -[test_hash_algorithms.js] -[test_hash_algorithms_wrap.js] -# bug 1124289 - run_test_in_child violates the sandbox on b2g and android -skip-if = toolkit == 'android' || toolkit == 'gonk' -[test_hmac.js] - -[test_sts_preloadlist_perwindowpb.js] -[test_sts_preloadlist_selfdestruct.js] -[test_sts_holepunch.js] -[test_sts_ipv4_ipv6.js] -[test_sts_fqdn.js] - -[test_sss_eviction.js] -[test_sss_readstate.js] -[test_sss_readstate_child.js] -support-files = sss_readstate_child_worker.js -# bug 1124289 - run_test_in_child violates the sandbox on b2g and android -skip-if = toolkit == 'android' || toolkit == 'gonk' -[test_sss_readstate_empty.js] -[test_sss_readstate_garbage.js] -[test_sss_readstate_huge.js] -[test_sss_savestate.js] - -[test_pinning_dynamic.js] -[test_pinning_header_parsing.js] - -[test_cert_dbKey.js] -[test_cert_keyUsage.js] -[test_logoutAndTeardown.js] -run-sequentially = hardcoded ports -[test_ocsp_must_staple.js] -run-sequentially = hardcoded ports -[test_ocsp_stapling.js] -run-sequentially = hardcoded ports +[test_add_preexisting_cert.js] [test_cert_blocklist.js] skip-if = buildapp == "b2g" -tags = addons -[test_ocsp_stapling_expired.js] +tags = addons psm +[test_cert_chains.js] run-sequentially = hardcoded ports -skip-if = (toolkit == 'gonk' && debug) # Bug 1029775 -[test_ocsp_stapling_with_intermediate.js] -run-sequentially = hardcoded ports -[test_ocsp_caching.js] -run-sequentially = hardcoded ports -[test_ocsp_required.js] -run-sequentially = hardcoded ports -[test_ocsp_timeout.js] -run-sequentially = hardcoded ports -[test_cert_signatures.js] -[test_ev_certs.js] -run-sequentially = hardcoded ports -[test_getchain.js] -[test_cert_overrides.js] -run-sequentially = hardcoded ports -[test_cert_override_bits_mismatches.js] -run-sequentially = hardcoded ports -[test_intermediate_basic_usage_constraints.js] -[test_name_constraints.js] -[test_cert_trust.js] -[test_cert_version.js] -[test_signed_apps.js] -[test_signed_apps-marketplace.js] -[test_signed_dir.js] -tags = addons - +[test_cert_dbKey.js] +[test_cert_eku-CA.js] [test_cert_eku-CA_EP.js] [test_cert_eku-CA_EP_NS_OS_SA_TS.js] -[test_cert_eku-CA.js] [test_cert_eku-CA_NS.js] [test_cert_eku-CA_OS.js] [test_cert_eku-CA_SA.js] @@ -115,16 +56,63 @@ tags = addons [test_cert_eku-SA.js] [test_cert_eku-SA_TS.js] [test_cert_eku-TS.js] - [test_cert_embedded_null.js] - -[test_cert_sha1.js] - -[test_pinning.js] +[test_cert_keyUsage.js] +[test_cert_overrides.js] +run-sequentially = hardcoded ports +[test_cert_override_bits_mismatches.js] +run-sequentially = hardcoded ports +[test_cert_sha1.js] +[test_cert_signatures.js] +[test_cert_trust.js] +[test_cert_version.js] +[test_certviewer_invalid_oids.js] +skip-if = toolkit == 'android' || buildapp == 'b2g' +[test_constructX509FromBase64.js] +[test_datasignatureverifier.js] +[test_ev_certs.js] +run-sequentially = hardcoded ports +[test_getchain.js] +[test_hash_algorithms.js] +[test_hash_algorithms_wrap.js] +# bug 1124289 - run_test_in_child violates the sandbox on b2g and android +skip-if = toolkit == 'android' || toolkit == 'gonk' +[test_hmac.js] +[test_intermediate_basic_usage_constraints.js] +[test_keysize.js] +[test_keysize_ev.js] +# OCSP requests in this test time out on slow B2G Emulator debug builds. +# See Bug 1147726. +skip-if = toolkit == 'gonk' && debug +run-sequentially = hardcoded ports +[test_logoutAndTeardown.js] +run-sequentially = hardcoded ports +[test_name_constraints.js] +[test_nsCertType.js] +run-sequentially = hardcoded ports +[test_nsIX509Cert_utf8.js] +[test_ocsp_caching.js] +run-sequentially = hardcoded ports +[test_ocsp_fetch_method.js] +# OCSP requests in this test time out on slow B2G Emulator debug builds. +# See Bug 1147725. +skip-if = toolkit == 'gonk' && debug +run-sequentially = hardcoded ports +[test_ocsp_must_staple.js] +run-sequentially = hardcoded ports +[test_ocsp_no_hsts_upgrade.js] +run-sequentially = hardcoded ports +[test_ocsp_required.js] +run-sequentially = hardcoded ports +[test_ocsp_stapling.js] +run-sequentially = hardcoded ports +[test_ocsp_stapling_expired.js] +run-sequentially = hardcoded ports +skip-if = (toolkit == 'gonk' && debug) # Bug 1029775 +[test_ocsp_stapling_with_intermediate.js] +run-sequentially = hardcoded ports +[test_ocsp_timeout.js] run-sequentially = hardcoded ports -# This test can take longer than 300 seconds on B2G emulator debug builds, so -# give it enough time to finish. See bug 1081128. -requesttimeoutfactor = 2 [test_ocsp_url.js] # OCSP requests in this test time out on slow B2G Emulator debug builds. # See Bug 1147725. @@ -132,30 +120,33 @@ requesttimeoutfactor = 2 # See Bug 1178988. skip-if = toolkit == 'gonk' run-sequentially = hardcoded ports -[test_ocsp_fetch_method.js] -# OCSP requests in this test time out on slow B2G Emulator debug builds. -# See Bug 1147725. -skip-if = toolkit == 'gonk' && debug +[test_pinning.js] run-sequentially = hardcoded ports -[test_ocsp_no_hsts_upgrade.js] -run-sequentially = hardcoded ports -[test_add_preexisting_cert.js] -[test_keysize.js] -[test_keysize_ev.js] -# OCSP requests in this test time out on slow B2G Emulator debug builds. -# See Bug 1147726. -skip-if = toolkit == 'gonk' && debug -run-sequentially = hardcoded ports -[test_cert_chains.js] -run-sequentially = hardcoded ports -[test_nsCertType.js] -run-sequentially = hardcoded ports -[test_nsIX509Cert_utf8.js] -[test_constructX509FromBase64.js] +# This test can take longer than 300 seconds on B2G emulator debug builds, so +# give it enough time to finish. See bug 1081128. +requesttimeoutfactor = 2 +[test_pinning_dynamic.js] +[test_pinning_header_parsing.js] +[test_signed_apps.js] +[test_signed_apps-marketplace.js] +[test_signed_dir.js] +tags = addons psm +[test_sss_eviction.js] +[test_sss_readstate.js] +[test_sss_readstate_child.js] +support-files = sss_readstate_child_worker.js +# bug 1124289 - run_test_in_child violates the sandbox on b2g and android +skip-if = toolkit == 'android' || toolkit == 'gonk' +[test_sss_readstate_empty.js] +[test_sss_readstate_garbage.js] +[test_sss_readstate_huge.js] +[test_sss_savestate.js] +[test_sts_fqdn.js] +[test_sts_holepunch.js] +[test_sts_ipv4_ipv6.js] +[test_sts_preloadlist_perwindowpb.js] +[test_sts_preloadlist_selfdestruct.js] [test_validity.js] run-sequentially = hardcoded ports -[test_certviewer_invalid_oids.js] -skip-if = toolkit == 'android' || buildapp == 'b2g' - [test_weak_crypto.js] firefox-appdir = browser From 89317a8c1f5ae934f46121d2e52b1753b883aef5 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Mon, 25 Jan 2016 16:00:34 -0600 Subject: [PATCH 025/218] Bug 1236104 - Revert pre-load cache compilation and tiny script limit. r=yury --- dom/base/nsScriptLoader.cpp | 15 --------------- js/src/jsapi.cpp | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp index e0555585e3a..fcdb55bcbf2 100644 --- a/dom/base/nsScriptLoader.cpp +++ b/dom/base/nsScriptLoader.cpp @@ -645,21 +645,6 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) // sheets. If the script comes from the network stream, cheat for // performance reasons and avoid a trip through the event loop. if (aElement->GetParserCreated() == FROM_PARSER_NETWORK) { - // Attempt to compile script off-thread first -- it reduces locking of - // the main thread for long time. - if (NumberOfProcessors() > 1 && - AttemptAsyncScriptCompile(request) == NS_OK) { - NS_ASSERTION(request->mProgress == nsScriptLoadRequest::Progress_Compiling, - "Request should be off-thread compiling now."); - NS_ASSERTION(!mParserBlockingRequest, - "There can be only one parser-blocking script at a time"); - NS_ASSERTION(mXSLTRequests.isEmpty(), - "Parser-blocking scripts and XSLT scripts in the same doc!"); - mParserBlockingRequest = request; - return true; - } - // And process a request if off-thread compilation heuristics think that - // non-async way will be faster. return ProcessRequest(request) == NS_ERROR_HTMLPARSER_BLOCK; } // Otherwise, we've got a document.written script, make a trip through diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 913e967f469..a05d057e625 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -4084,7 +4084,7 @@ JS::CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& opt JS_PUBLIC_API(bool) JS::CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length) { - static const size_t TINY_LENGTH = 25 * 1000; + static const size_t TINY_LENGTH = 5 * 1000; static const size_t HUGE_LENGTH = 100 * 1000; // These are heuristics which the caller may choose to ignore (e.g., for From aa0349a64931532b7d1e608dbfd8ca9f0d9d3166 Mon Sep 17 00:00:00 2001 From: Sander Mathijs van Veen Date: Tue, 12 Jan 2016 07:08:00 +0100 Subject: [PATCH 026/218] Bug 1235641 - Add line and column info to dump bytecode basic blocks. r=sstangl --- js/src/jsopcode.cpp | 10 +++++++--- js/src/jsopcode.h | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 78c98948cbd..a0e5be46679 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -147,12 +147,16 @@ js::StackDefs(JSScript* script, jsbytecode* pc) const char * PCCounts::numExecName = "interp"; void -js::DumpIonScriptCounts(Sprinter* sp, jit::IonScriptCounts* ionCounts) +js::DumpIonScriptCounts(Sprinter* sp, HandleScript script, + jit::IonScriptCounts* ionCounts) { Sprint(sp, "IonScript [%lu blocks]:\n", ionCounts->numBlocks()); for (size_t i = 0; i < ionCounts->numBlocks(); i++) { const jit::IonBlockCounts& block = ionCounts->block(i); - Sprint(sp, "BB #%lu [%05u]", block.id(), block.offset()); + unsigned lineNumber = 0, columnNumber = 0; + lineNumber = PCToLineNumber(script, script->offsetToPC(block.offset()), &columnNumber); + Sprint(sp, "BB #%lu [%05u,%u,%u]", block.id(), block.offset(), + lineNumber, columnNumber); if (block.description()) Sprint(sp, " [inlined %s]", block.description()); for (size_t j = 0; j < block.numSuccessors(); j++) @@ -189,7 +193,7 @@ js::DumpPCCounts(JSContext* cx, HandleScript script, Sprinter* sp) jit::IonScriptCounts* ionCounts = script->getIonCounts(); while (ionCounts) { - DumpIonScriptCounts(sp, ionCounts); + DumpIonScriptCounts(sp, script, ionCounts); ionCounts = ionCounts->previous(); } } diff --git a/js/src/jsopcode.h b/js/src/jsopcode.h index d1c9d3f0ea2..b46e7334094 100644 --- a/js/src/jsopcode.h +++ b/js/src/jsopcode.h @@ -846,7 +846,8 @@ DumpPCCounts(JSContext* cx, JS::Handle script, Sprinter* sp); namespace jit { struct IonScriptCounts; } void -DumpIonScriptCounts(js::Sprinter* sp, jit::IonScriptCounts* ionCounts); +DumpIonScriptCounts(js::Sprinter* sp, HandleScript script, + jit::IonScriptCounts* ionCounts); void DumpCompartmentPCCounts(JSContext* cx); From 020e5ddb3fc9fc4614812b81223a3de3259fb99e Mon Sep 17 00:00:00 2001 From: "Nicolas B. Pierron" Date: Wed, 27 Jan 2016 10:19:41 +0000 Subject: [PATCH 027/218] Bug 1233178 - Move ScriptCounts allocation outside the HashMap. r=bhackett --- .../Script-getOffsetsCoverage-bug1233178.js | 13 +++++++++++ js/src/jscompartment.cpp | 3 ++- js/src/jsscript.cpp | 23 +++++++++++++++---- js/src/jsscript.h | 2 +- 4 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 js/src/jit-test/tests/debug/Script-getOffsetsCoverage-bug1233178.js diff --git a/js/src/jit-test/tests/debug/Script-getOffsetsCoverage-bug1233178.js b/js/src/jit-test/tests/debug/Script-getOffsetsCoverage-bug1233178.js new file mode 100644 index 00000000000..633c8176b70 --- /dev/null +++ b/js/src/jit-test/tests/debug/Script-getOffsetsCoverage-bug1233178.js @@ -0,0 +1,13 @@ +gczeal(2); +g = newGlobal(); +dbg = Debugger(g); +function loop() { + for (var i = 0; i < 10; i++) + debugger; +} +g.eval(loop.toSource()); +dbg.onDebuggerStatement = function(f) { + f.script.getOffsetsCoverage(); +} +dbg.collectCoverageInfo = true; +g.eval("loop")(); diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 37d61d3fccc..caf957fecc0 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -1080,8 +1080,9 @@ JSCompartment::clearScriptCounts() // Clear all hasScriptCounts_ flags of JSScript, in order to release all // ScriptCounts entry of the current compartment. for (ScriptCountsMap::Range r = scriptCountsMap->all(); !r.empty(); r.popFront()) { - ScriptCounts* value = &r.front().value(); + ScriptCounts* value = r.front().value(); r.front().key()->takeOverScriptCountsMapEntry(value); + js_delete(value); } js_delete(scriptCountsMap); diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 208bf2a7ea4..0fd388a28ff 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -14,6 +14,7 @@ #include "mozilla/MathAlgorithms.h" #include "mozilla/MemoryReporting.h" #include "mozilla/PodOperations.h" +#include "mozilla/ScopeExit.h" #include "mozilla/Vector.h" #include @@ -1443,14 +1444,25 @@ JSScript::initScriptCounts(JSContext* cx) compartment()->scriptCountsMap = map; } - // Register the current ScriptCount in the compartment's map. - if (!map->putNew(this, Move(base))) { + // Allocate the ScriptCounts. + ScriptCounts* sc = cx->new_(Move(base)); + if (!sc) { + ReportOutOfMemory(cx); + return false; + } + auto guardScriptCounts = mozilla::MakeScopeExit([&] () { + js_delete(sc); + }); + + // Register the current ScriptCounts in the compartment's map. + if (!map->putNew(this, sc)) { ReportOutOfMemory(cx); return false; } // safe to set this; we can't fail after this point. hasScriptCounts_ = true; + guardScriptCounts.release(); // Enable interrupts in any interpreter frames running on this script. This // is used to let the interpreter increment the PCCounts, if present. @@ -1475,7 +1487,7 @@ ScriptCounts& JSScript::getScriptCounts() { ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this); - return p->value(); + return *p->value(); } js::PCCounts* @@ -1635,7 +1647,7 @@ JSScript::takeOverScriptCountsMapEntry(ScriptCounts* entryValue) { #ifdef DEBUG ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this); - MOZ_ASSERT(entryValue == &p->value()); + MOZ_ASSERT(entryValue == p->value()); #endif hasScriptCounts_ = false; } @@ -1644,7 +1656,8 @@ void JSScript::releaseScriptCounts(ScriptCounts* counts) { ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this); - *counts = Move(p->value()); + *counts = Move(*p->value()); + js_delete(p->value()); compartment()->scriptCountsMap->remove(p); hasScriptCounts_ = false; } diff --git a/js/src/jsscript.h b/js/src/jsscript.h index cd11a6f6f94..68caa28cfb7 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -513,7 +513,7 @@ class ScriptCounts // the calls to the JSScript::finalize function which are used to aggregate code // coverage results on the compartment. typedef HashMap, SystemAllocPolicy> ScriptCountsMap; From d07db5d65d49ff6e57fd2f34a997b042a544f00d Mon Sep 17 00:00:00 2001 From: Ethan Lin Date: Thu, 7 Jan 2016 21:45:00 +0100 Subject: [PATCH 028/218] Bug 1237193 - Fix WebGL getActiveUniforms return type. r=jgilbert, r=smaug --- dom/canvas/WebGL2Context.h | 9 ++- dom/canvas/WebGL2ContextUniforms.cpp | 72 +++++++++++++++++++++--- dom/webidl/WebGL2RenderingContext.webidl | 2 +- 3 files changed, 70 insertions(+), 13 deletions(-) diff --git a/dom/canvas/WebGL2Context.h b/dom/canvas/WebGL2Context.h index 6949c7aab10..be014440afa 100644 --- a/dom/canvas/WebGL2Context.h +++ b/dom/canvas/WebGL2Context.h @@ -360,9 +360,12 @@ public: void GetUniformIndices(WebGLProgram* program, const dom::Sequence& uniformNames, dom::Nullable< nsTArray >& retval); - void GetActiveUniforms(WebGLProgram* program, - const dom::Sequence& uniformIndices, GLenum pname, - dom::Nullable< nsTArray >& retval); + void GetActiveUniforms(JSContext* cx, + WebGLProgram* program, + const dom::Sequence& uniformIndices, + GLenum pname, + JS::MutableHandleValue retval); + GLuint GetUniformBlockIndex(WebGLProgram* program, const nsAString& uniformBlockName); void GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program, GLuint uniformBlockIndex, GLenum pname, diff --git a/dom/canvas/WebGL2ContextUniforms.cpp b/dom/canvas/WebGL2ContextUniforms.cpp index ff079e05593..ccc6622d779 100644 --- a/dom/canvas/WebGL2ContextUniforms.cpp +++ b/dom/canvas/WebGL2ContextUniforms.cpp @@ -318,20 +318,38 @@ WebGL2Context::GetUniformIndices(WebGLProgram* program, program->GetUniformIndices(uniformNames, retval); } +static bool +ValidateUniformEnum(WebGLContext* webgl, GLenum pname, const char* info) +{ + switch (pname) { + case LOCAL_GL_UNIFORM_TYPE: + case LOCAL_GL_UNIFORM_SIZE: + case LOCAL_GL_UNIFORM_BLOCK_INDEX: + case LOCAL_GL_UNIFORM_OFFSET: + case LOCAL_GL_UNIFORM_ARRAY_STRIDE: + case LOCAL_GL_UNIFORM_MATRIX_STRIDE: + case LOCAL_GL_UNIFORM_IS_ROW_MAJOR: + return true; + + default: + webgl->ErrorInvalidEnum("%s: invalid pname: %s", info, webgl->EnumName(pname)); + return false; + } +} + void -WebGL2Context::GetActiveUniforms(WebGLProgram* program, +WebGL2Context::GetActiveUniforms(JSContext* cx, + WebGLProgram* program, const dom::Sequence& uniformIndices, GLenum pname, - dom::Nullable< nsTArray >& retval) + JS::MutableHandleValue retval) { - retval.SetNull(); + retval.set(JS::NullValue()); if (IsContextLost()) return; - if (pname == LOCAL_GL_UNIFORM_NAME_LENGTH) { - ErrorInvalidEnumInfo("getActiveUniforms: pname", pname); + if (!ValidateUniformEnum(this, pname, "getActiveUniforms")) return; - } if (!ValidateObject("getActiveUniforms: program", program)) return; @@ -341,12 +359,48 @@ WebGL2Context::GetActiveUniforms(WebGLProgram* program, return; GLuint progname = program->mGLName; - nsTArray& arr = retval.SetValue(); - arr.SetLength(count); + Vector samples; + samples.resize(count); MakeContextCurrent(); gl->fGetActiveUniformsiv(progname, count, uniformIndices.Elements(), pname, - arr.Elements()); + samples.begin()); + + JS::Rooted array(cx, JS_NewArrayObject(cx, count)); + if (!array) { + return; + } + + switch (pname) { + case LOCAL_GL_UNIFORM_TYPE: + case LOCAL_GL_UNIFORM_SIZE: + case LOCAL_GL_UNIFORM_BLOCK_INDEX: + case LOCAL_GL_UNIFORM_OFFSET: + case LOCAL_GL_UNIFORM_ARRAY_STRIDE: + case LOCAL_GL_UNIFORM_MATRIX_STRIDE: + for (uint32_t i = 0; i < count; ++i) { + JS::RootedValue value(cx); + value = JS::Int32Value(samples[i]); + if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE)) { + return; + } + } + break; + case LOCAL_GL_UNIFORM_IS_ROW_MAJOR: + for (uint32_t i = 0; i < count; ++i) { + JS::RootedValue value(cx); + value = JS::BooleanValue(samples[i]); + if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE)) { + return; + } + } + break; + + default: + return; + } + + retval.setObjectOrNull(array); } GLuint diff --git a/dom/webidl/WebGL2RenderingContext.webidl b/dom/webidl/WebGL2RenderingContext.webidl index 5af0f0cd26b..3cfd1400c76 100644 --- a/dom/webidl/WebGL2RenderingContext.webidl +++ b/dom/webidl/WebGL2RenderingContext.webidl @@ -475,7 +475,7 @@ interface WebGL2RenderingContext : WebGLRenderingContext // GLintptr here, otherwise interface generator returns error. (WebGLBuffer or GLintptr)? getIndexedParameter(GLenum target, GLuint index); sequence? getUniformIndices(WebGLProgram? program, sequence uniformNames); - sequence? getActiveUniforms(WebGLProgram? program, sequence uniformIndices, GLenum pname); + any getActiveUniforms(WebGLProgram? program, sequence uniformIndices, GLenum pname); GLuint getUniformBlockIndex(WebGLProgram? program, DOMString uniformBlockName); [Throws] (GLuint or Uint32Array or GLboolean)? getActiveUniformBlockParameter(WebGLProgram? program, GLuint uniformBlockIndex, GLenum pname); From cc780523eed2d30092f6a2e4b0977b88998ec96e Mon Sep 17 00:00:00 2001 From: Kaku Kuo Date: Tue, 19 Jan 2016 14:35:01 +0800 Subject: [PATCH 029/218] Bug 1239300 - reject promise with null while creating imagebitmap from empty blob; r=smaug --- dom/canvas/ImageBitmap.cpp | 6 +++--- dom/canvas/test/imagebitmap_bug1239300.js | 19 +++++++++++++++++++ dom/canvas/test/imagebitmap_on_worker.js | 5 +++++ dom/canvas/test/mochitest.ini | 9 +++++++++ dom/canvas/test/test_imagebitmap.html | 2 ++ .../test/test_imagebitmap_on_worker.html | 3 +++ dom/promise/Promise.cpp | 6 ++++++ dom/promise/Promise.h | 2 ++ 8 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 dom/canvas/test/imagebitmap_bug1239300.js diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp index 2c7c3d412a2..6b6d7826b8f 100644 --- a/dom/canvas/ImageBitmap.cpp +++ b/dom/canvas/ImageBitmap.cpp @@ -1065,7 +1065,7 @@ private: RefPtr data = DecodeAndCropBlob(*mBlob, mCropRect); if (NS_WARN_IF(!data)) { - mPromise->MaybeReject(NS_ERROR_NOT_AVAILABLE); + mPromise->MaybeRejectWithNull(); return nullptr; } @@ -1143,9 +1143,9 @@ private: mPromise->MaybeReject(rv); return nullptr; } - + if (NS_WARN_IF(!data)) { - mPromise->MaybeReject(NS_ERROR_NOT_AVAILABLE); + mPromise->MaybeRejectWithNull(); return nullptr; } diff --git a/dom/canvas/test/imagebitmap_bug1239300.js b/dom/canvas/test/imagebitmap_bug1239300.js new file mode 100644 index 00000000000..16a77a97777 --- /dev/null +++ b/dom/canvas/test/imagebitmap_bug1239300.js @@ -0,0 +1,19 @@ +function testBug1239300() { + return new Promise(function(resolve, reject) { + createImageBitmap(new Blob()).then( + function() { + ok(false, "The promise should be rejected with null."); + reject(); + }, + function(result) { + if (result == null) { + ok(true, "The promise should be rejected with null."); + resolve(); + } else { + ok(false, "The promise should be rejected with null."); + reject(); + } + } + ); + }); +} \ No newline at end of file diff --git a/dom/canvas/test/imagebitmap_on_worker.js b/dom/canvas/test/imagebitmap_on_worker.js index 96a01e459f8..be704671091 100644 --- a/dom/canvas/test/imagebitmap_on_worker.js +++ b/dom/canvas/test/imagebitmap_on_worker.js @@ -1,3 +1,5 @@ +importScripts("imagebitmap_bug1239300.js"); + function ok(expect, msg) { postMessage({type: "status", status: !!expect, msg: msg}); } @@ -77,5 +79,8 @@ onmessage = function(event) { promiseThrows(createImageBitmap(source), event.data.msg); } doneTask(); + } else if (event.data.type == "testBug1239300") { + var promise = testBug1239300(); + promise.then(doneTask, doneTask); } }; \ No newline at end of file diff --git a/dom/canvas/test/mochitest.ini b/dom/canvas/test/mochitest.ini index da25c4ef6a7..811f2a28edb 100644 --- a/dom/canvas/test/mochitest.ini +++ b/dom/canvas/test/mochitest.ini @@ -24,6 +24,7 @@ support-files = image_transparent50.png image_yellow.png image_yellow75.png + imagebitmap_bug1239300.js imagebitmap_on_worker.js imagebitmap_structuredclone.js imagebitmap_structuredclone_iframe.html @@ -247,13 +248,21 @@ support-files = captureStream_common.js support-files = file_drawWindow_source.html file_drawWindow_common.js skip-if = (buildapp == 'b2g' && toolkit != 'gonk') [test_imagebitmap.html] +tags = imagebitmap [test_imagebitmap_close.html] +tags = imagebitmap [test_imagebitmap_cropping.html] +tags = imagebitmap [test_imagebitmap_on_worker.html] +tags = imagebitmap [test_imagebitmap_structuredclone.html] +tags = imagebitmap [test_imagebitmap_structuredclone_iframe.html] +tags = imagebitmap [test_imagebitmap_structuredclone_window.html] +tags = imagebitmap [test_imagebitmap_transfer.html] +tags = imagebitmap [test_ImageData_ctor.html] [test_isPointInStroke.html] [test_mozDashOffset.html] diff --git a/dom/canvas/test/test_imagebitmap.html b/dom/canvas/test/test_imagebitmap.html index df9a2ec4af4..9701159cbe3 100644 --- a/dom/canvas/test/test_imagebitmap.html +++ b/dom/canvas/test/test_imagebitmap.html @@ -11,6 +11,7 @@ + + + + +
    + From 72402ce46fc383f792d1ba310f939bed2ebc7589 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Wed, 27 Jan 2016 02:45:22 +0200 Subject: [PATCH 082/218] Bug 1241485 - Increase the limit for workers per-origin, r=khuey --- dom/workers/test/mochitest.ini | 1 + dom/workers/test/test_bug1241485.html | 82 +++++++++++++++++++++++++++ modules/libpref/init/all.js | 2 +- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 dom/workers/test/test_bug1241485.html diff --git a/dom/workers/test/mochitest.ini b/dom/workers/test/mochitest.ini index 7bb3539b3d1..29a78669247 100644 --- a/dom/workers/test/mochitest.ini +++ b/dom/workers/test/mochitest.ini @@ -141,6 +141,7 @@ support-files = [test_bug1132395.html] skip-if = true # bug 1176225 [test_bug1132924.html] +[test_bug1241485.html] [test_chromeWorker.html] [test_clearTimeouts.html] [test_close.html] diff --git a/dom/workers/test/test_bug1241485.html b/dom/workers/test/test_bug1241485.html new file mode 100644 index 00000000000..cfa56aad3c8 --- /dev/null +++ b/dom/workers/test/test_bug1241485.html @@ -0,0 +1,82 @@ + + + + + + Test for Bug 1241485 + + + + + +Mozilla Bug 1241485 +

    + +
    +
    + + diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 14783f8ee31..952526438e9 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -142,7 +142,7 @@ pref("dom.select_events.enabled", false); // Whether or not Web Workers are enabled. pref("dom.workers.enabled", true); // The number of workers per domain allowed to run concurrently. -pref("dom.workers.maxPerDomain", 20); +pref("dom.workers.maxPerDomain", 50); pref("dom.serviceWorkers.enabled", false); From cf0f05743a32cec5c91b49b061860b09231f22ae Mon Sep 17 00:00:00 2001 From: Hannes Verschore Date: Wed, 27 Jan 2016 11:20:10 -0500 Subject: [PATCH 083/218] Bug 1241087: SharedStubs: Enable shared stubs by default for ion, r=jandem --- js/src/jit/JitOptions.cpp | 2 +- js/src/shell/js.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/jit/JitOptions.cpp b/js/src/jit/JitOptions.cpp index 8d43464ad5f..d05c726f0ed 100644 --- a/js/src/jit/JitOptions.cpp +++ b/js/src/jit/JitOptions.cpp @@ -111,7 +111,7 @@ DefaultJitOptions::DefaultJitOptions() SET_DEFAULT(disableScalarReplacement, false); // Toggles whether shared stubs are used in Ionmonkey. - SET_DEFAULT(disableSharedStubs, true); + SET_DEFAULT(disableSharedStubs, false); // Toggles whether sincos optimization is globally disabled. // See bug984018: The MacOS is the only one that has the sincos fast. diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 81c85c02127..cb2c3813504 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -6809,7 +6809,7 @@ main(int argc, char** argv, char** envp) ) #endif || !op.addStringOption('\0', "ion-shared-stubs", "on/off", - "Use shared stubs (default: off, on to enable)") + "Use shared stubs (default: on, off to enable)") || !op.addStringOption('\0', "ion-scalar-replacement", "on/off", "Scalar Replacement (default: on, off to disable)") || !op.addStringOption('\0', "ion-gvn", "[mode]", From a9116fde9e2c275fecbef8a90b2534c7f61816ac Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Mon, 18 Jan 2016 22:12:55 +0000 Subject: [PATCH 084/218] Bug 1240601 - Set timeout on socket in transport.wait_for_port; r=automatedtester If the client is able to connect but the server never sends any data, the socket should time out in order for the function not to hang forever. That said, polling for ports like this is inherently racy and we should instead specify and bind what port we wish Marionette to start on in the future. --- .../marionette/transport/marionette_transport/transport.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/testing/marionette/transport/marionette_transport/transport.py b/testing/marionette/transport/marionette_transport/transport.py index 28ab714cd6e..455760a5787 100644 --- a/testing/marionette/transport/marionette_transport/transport.py +++ b/testing/marionette/transport/marionette_transport/transport.py @@ -289,22 +289,23 @@ class TcpTransport(object): def wait_for_port(host, port, timeout=60): - """ Wait for the specified host/port to be available.""" + """Wait for the specified host/port to become available.""" starttime = datetime.datetime.now() poll_interval = 0.1 while datetime.datetime.now() - starttime < datetime.timedelta(seconds=timeout): sock = None try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(0.5) sock.connect((host, port)) data = sock.recv(16) sock.close() - if ':' in data: + if ":" in data: return True except socket.error: pass finally: - if sock: + if sock is not None: sock.close() time.sleep(poll_interval) return False From 9605bb5fb50f2a058937097713eac5d814538e0b Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Thu, 21 Jan 2016 11:36:36 -0500 Subject: [PATCH 085/218] Bug 1241522 - handle OOM in nsExpatDriver::HandleCharacterData; r=hsivonen --- parser/htmlparser/nsExpatDriver.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/parser/htmlparser/nsExpatDriver.cpp b/parser/htmlparser/nsExpatDriver.cpp index 2e672f99c50..ac66f6a1916 100644 --- a/parser/htmlparser/nsExpatDriver.cpp +++ b/parser/htmlparser/nsExpatDriver.cpp @@ -33,6 +33,7 @@ #include "mozilla/Logging.h" +using mozilla::fallible; using mozilla::LogLevel; #define kExpatSeparatorChar 0xFFFF @@ -415,7 +416,9 @@ nsExpatDriver::HandleCharacterData(const char16_t *aValue, NS_ASSERTION(mSink, "content sink not found!"); if (mInCData) { - mCDataText.Append(aValue, aLength); + if (!mCDataText.Append(aValue, aLength, fallible)) { + MaybeStopParser(NS_ERROR_OUT_OF_MEMORY); + } } else if (mSink) { nsresult rv = mSink->HandleCharacterData(aValue, aLength); From a6b1227b8ae2f239efdb38da911cb2388cddae6e Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 26 Jan 2016 11:30:03 -0500 Subject: [PATCH 086/218] Bug 1243430 - remove stray carriage returns from MessagePump.cpp; r=me DONTBUILD because whitespace-only changes are trivial. --- ipc/glue/MessagePump.cpp | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/ipc/glue/MessagePump.cpp b/ipc/glue/MessagePump.cpp index 01fb7148377..a7b62a95e3a 100644 --- a/ipc/glue/MessagePump.cpp +++ b/ipc/glue/MessagePump.cpp @@ -418,31 +418,31 @@ void MessagePumpForNonMainUIThreads::DoRunLoop() ti->SetObserver(nullptr); } - -NS_IMETHODIMP -MessagePumpForNonMainUIThreads::OnDispatchedEvent(nsIThreadInternal *thread) -{ - // If our thread is sleeping in DoRunLoop's call to WaitForWork() and an - // event posts to the nsIThread event queue - break our thread out of - // chromium's WaitForWork. - if (GetInWait()) { - ScheduleWork(); - } - return NS_OK; -} - -NS_IMETHODIMP -MessagePumpForNonMainUIThreads::OnProcessNextEvent(nsIThreadInternal *thread, - bool mayWait) -{ - return NS_OK; -} - -NS_IMETHODIMP -MessagePumpForNonMainUIThreads::AfterProcessNextEvent(nsIThreadInternal *thread, - bool eventWasProcessed) -{ - return NS_OK; -} + +NS_IMETHODIMP +MessagePumpForNonMainUIThreads::OnDispatchedEvent(nsIThreadInternal *thread) +{ + // If our thread is sleeping in DoRunLoop's call to WaitForWork() and an + // event posts to the nsIThread event queue - break our thread out of + // chromium's WaitForWork. + if (GetInWait()) { + ScheduleWork(); + } + return NS_OK; +} + +NS_IMETHODIMP +MessagePumpForNonMainUIThreads::OnProcessNextEvent(nsIThreadInternal *thread, + bool mayWait) +{ + return NS_OK; +} + +NS_IMETHODIMP +MessagePumpForNonMainUIThreads::AfterProcessNextEvent(nsIThreadInternal *thread, + bool eventWasProcessed) +{ + return NS_OK; +} #endif // XP_WIN From 9ef7fdd2d12709e31dc7b4aebd9cbf90255912e7 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 27 Jan 2016 11:58:41 +0100 Subject: [PATCH 087/218] Bug 1243031: Throw when WebAssembly is not supported; r=luke And in deterministic builds, print an error on stderr so that fuzzers know that they need to abort differential testing fuzzing. --- js/src/asmjs/Wasm.cpp | 52 +++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/js/src/asmjs/Wasm.cpp b/js/src/asmjs/Wasm.cpp index b43c315188b..b30a7bb62ae 100644 --- a/js/src/asmjs/Wasm.cpp +++ b/js/src/asmjs/Wasm.cpp @@ -553,9 +553,41 @@ DecodeModule(JSContext* cx, UniqueChars filename, const uint8_t* bytes, uint32_t /*****************************************************************************/ // JS entry poitns +static bool +SupportsWasm(JSContext* cx) +{ +#if defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_ARM64) + return false; +#endif + + if (!cx->jitSupportsFloatingPoint()) + return false; + + if (cx->gcSystemPageSize() != AsmJSPageSize) + return false; + + return true; +} + +static bool +CheckWasmSupport(JSContext* cx) +{ + if (!SupportsWasm(cx)) { +#ifdef JS_MORE_DETERMINISTIC + fprintf(stderr, "WebAssembly is not supported on the current device.\n"); +#endif // JS_MORE_DETERMINISTIC + JS_ReportError(cx, "WebAssembly is not supported on the current device."); + return false; + } + return true; +} + static bool WasmEval(JSContext* cx, unsigned argc, Value* vp) { + if (!CheckWasmSupport(cx)) + return false; + CallArgs args = CallArgsFromVp(argc, vp); RootedObject callee(cx, &args.callee()); @@ -668,26 +700,8 @@ static const JSFunctionSpecWithHelp WasmTestingFunctions[] = { JS_FS_HELP_END }; -static bool -SupportsWasm(JSContext* cx) -{ -#if defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_ARM64) - return false; -#endif - - if (!cx->jitSupportsFloatingPoint()) - return false; - - if (cx->gcSystemPageSize() != AsmJSPageSize) - return false; - - return true; -} - bool wasm::DefineTestingFunctions(JSContext* cx, HandleObject globalObj) { - if (SupportsWasm(cx)) - return JS_DefineFunctionsWithHelp(cx, globalObj, WasmTestingFunctions); - return true; + return JS_DefineFunctionsWithHelp(cx, globalObj, WasmTestingFunctions); } From 004117ad0426edf76a6acbd36211cafdd4460074 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 27 Jan 2016 10:51:03 +0100 Subject: [PATCH 088/218] Bug 1242949: Implement Block in WebAssembly; r=luke --- js/src/asmjs/AsmJS.cpp | 19 +++----- js/src/asmjs/Wasm.cpp | 24 ++++++++++ js/src/asmjs/WasmBinary.h | 2 - js/src/asmjs/WasmGenerator.cpp | 6 +-- js/src/asmjs/WasmGenerator.h | 1 + js/src/asmjs/WasmIonCompile.cpp | 24 ++++------ js/src/asmjs/WasmIonCompile.h | 3 +- js/src/asmjs/WasmText.cpp | 69 ++++++++++++++++++++++++++++- js/src/jit-test/tests/wasm/basic.js | 21 +++++++++ 9 files changed, 133 insertions(+), 36 deletions(-) diff --git a/js/src/asmjs/AsmJS.cpp b/js/src/asmjs/AsmJS.cpp index 50977b2ac22..cdddcbb401e 100644 --- a/js/src/asmjs/AsmJS.cpp +++ b/js/src/asmjs/AsmJS.cpp @@ -2768,14 +2768,6 @@ class MOZ_STACK_CLASS FunctionValidator return writeOp(SimdToExpr(simdType, op)); } - MOZ_WARN_UNUSED_RESULT - bool writeDebugCheckPoint() { -#ifdef DEBUG - return writeOp(Expr::DebugCheckPoint); -#endif - return true; - } - MOZ_WARN_UNUSED_RESULT bool writeU8(uint8_t u8) { return encoder().writeU8(u8); @@ -5704,7 +5696,7 @@ CheckComma(FunctionValidator& f, ParseNode* comma, Type* type) MOZ_ASSERT(comma->isKind(PNK_COMMA)); ParseNode* operands = ListHead(comma); - if (!f.writeOp(Expr::Block) || !f.writeU32(ListLength(comma))) + if (!f.writeOp(Expr::Block) || !f.writeVarU32(ListLength(comma))) return false; ParseNode* pn = operands; @@ -5713,8 +5705,7 @@ CheckComma(FunctionValidator& f, ParseNode* comma, Type* type) return false; } - return CheckExpr(f, pn, type) && - f.writeDebugCheckPoint(); + return CheckExpr(f, pn, type); } static bool @@ -6245,7 +6236,7 @@ CheckFor(FunctionValidator& f, ParseNode* forStmt) if (maybeInc && !CheckAsExprStatement(f, maybeInc)) return false; - return f.writeDebugCheckPoint(); + return true; } static bool @@ -6561,7 +6552,7 @@ CheckStatementList(FunctionValidator& f, ParseNode* stmtList) { MOZ_ASSERT(stmtList->isKind(PNK_STATEMENTLIST)); - if (!f.writeOp(Expr::Block) || !f.writeU32(ListLength(stmtList))) + if (!f.writeOp(Expr::Block) || !f.writeVarU32(ListLength(stmtList))) return false; for (ParseNode* stmt = ListHead(stmtList); stmt; stmt = NextNode(stmt)) { @@ -6569,7 +6560,7 @@ CheckStatementList(FunctionValidator& f, ParseNode* stmtList) return false; } - return f.writeDebugCheckPoint(); + return true; } static bool diff --git a/js/src/asmjs/Wasm.cpp b/js/src/asmjs/Wasm.cpp index b30a7bb62ae..f903fcfa3a7 100644 --- a/js/src/asmjs/Wasm.cpp +++ b/js/src/asmjs/Wasm.cpp @@ -201,6 +201,28 @@ DecodeSetLocal(FunctionDecoder& f, ExprType expected) return CheckType(f, localType, expected); } +static bool +DecodeBlock(FunctionDecoder& f, ExprType expected) +{ + uint32_t numExprs; + if (!f.d().readVarU32(&numExprs)) + return f.fail("unable to read block's number of expressions"); + + if (numExprs) { + for (uint32_t i = 0; i < numExprs - 1; i++) { + if (!DecodeExpr(f, ExprType::Void)) + return false; + } + if (!DecodeExpr(f, expected)) + return false; + } else { + if (!CheckType(f, ExprType::Void, expected)) + return false; + } + + return true; +} + static bool DecodeExpr(FunctionDecoder& f, ExprType expected) { @@ -217,6 +239,8 @@ DecodeExpr(FunctionDecoder& f, ExprType expected) return DecodeGetLocal(f, expected); case Expr::SetLocal: return DecodeSetLocal(f, expected); + case Expr::Block: + return DecodeBlock(f, expected); default: break; } diff --git a/js/src/asmjs/WasmBinary.h b/js/src/asmjs/WasmBinary.h index 2fe9d78afdd..4c9a5fd9475 100644 --- a/js/src/asmjs/WasmBinary.h +++ b/js/src/asmjs/WasmBinary.h @@ -206,8 +206,6 @@ enum class Expr : uint16_t InterruptCheckHead, InterruptCheckLoop, - DebugCheckPoint, - I32Min, I32Max, diff --git a/js/src/asmjs/WasmGenerator.cpp b/js/src/asmjs/WasmGenerator.cpp index 62c5e03e9f1..505a9899bb0 100644 --- a/js/src/asmjs/WasmGenerator.cpp +++ b/js/src/asmjs/WasmGenerator.cpp @@ -267,7 +267,7 @@ ModuleGenerator::allocateGlobalVar(ValType type, bool isConst, uint32_t* index) void ModuleGenerator::initSig(uint32_t sigIndex, Sig&& sig) { - MOZ_ASSERT(module_->kind == ModuleKind::AsmJS); + MOZ_ASSERT(isAsmJS()); MOZ_ASSERT(sigIndex == numSigs_); numSigs_++; @@ -285,7 +285,7 @@ ModuleGenerator::sig(uint32_t index) const bool ModuleGenerator::initFuncSig(uint32_t funcIndex, uint32_t sigIndex) { - MOZ_ASSERT(module_->kind == ModuleKind::AsmJS); + MOZ_ASSERT(isAsmJS()); MOZ_ASSERT(funcIndex == module_->numFuncs); MOZ_ASSERT(!shared_->funcSigs[funcIndex]); @@ -304,7 +304,7 @@ ModuleGenerator::funcSig(uint32_t funcIndex) const bool ModuleGenerator::initImport(uint32_t importIndex, uint32_t sigIndex, uint32_t globalDataOffset) { - MOZ_ASSERT(module_->kind == ModuleKind::AsmJS); + MOZ_ASSERT(isAsmJS()); MOZ_ASSERT(importIndex == module_->imports.length()); if (!addImport(sig(sigIndex), globalDataOffset)) return false; diff --git a/js/src/asmjs/WasmGenerator.h b/js/src/asmjs/WasmGenerator.h index d1d248fce25..508982ccf4b 100644 --- a/js/src/asmjs/WasmGenerator.h +++ b/js/src/asmjs/WasmGenerator.h @@ -166,6 +166,7 @@ class MOZ_STACK_CLASS ModuleGenerator bool init(UniqueModuleGeneratorData shared, ModuleKind = ModuleKind::Wasm); + bool isAsmJS() const { return module_->kind == ModuleKind::AsmJS; } CompileArgs args() const { return module_->compileArgs; } jit::MacroAssembler& masm() { return masm_; } const Uint32Vector& funcEntryOffsets() const { return funcEntryOffsets_; } diff --git a/js/src/asmjs/WasmIonCompile.cpp b/js/src/asmjs/WasmIonCompile.cpp index 6d461605e1f..eb0a00ee296 100644 --- a/js/src/asmjs/WasmIonCompile.cpp +++ b/js/src/asmjs/WasmIonCompile.cpp @@ -1195,10 +1195,6 @@ class FunctionCompiler *column = sc.column; } - void assertDebugCheckPoint() { - MOZ_ASSERT(readOpcode() == Expr::DebugCheckPoint); - } - bool done() const { return decoder_.done(); } /*************************************************************************/ @@ -2470,8 +2466,6 @@ EmitFor(FunctionCompiler& f, Expr expr, const LabelVector* maybeLabels) return false; } - f.assertDebugCheckPoint(); - return f.closeLoop(loopEntry, afterLoop); } @@ -2635,15 +2629,16 @@ EmitRet(FunctionCompiler& f) static bool EmitBlock(FunctionCompiler& f, ExprType type, MDefinition** def) { - size_t numStmt = f.readU32(); - for (size_t i = 1; i < numStmt; i++) { - // Fine to clobber def, we only want the last use. - if (!EmitExprStmt(f, def)) + uint32_t numStmts = f.readVarU32(); + if (numStmts) { + for (uint32_t i = 0; i < numStmts - 1; i++) { + // Fine to clobber def, we only want the last use. + if (!EmitExprStmt(f, def)) + return false; + } + if (!EmitExpr(f, type, def)) return false; } - if (numStmt && !EmitExpr(f, type, def)) - return false; - f.assertDebugCheckPoint(); return true; } @@ -2967,7 +2962,6 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may case Expr::I64StoreMem32: case Expr::I64StoreMem: MOZ_CRASH("NYI"); - case Expr::DebugCheckPoint: case Expr::Unreachable: break; case Expr::Limit: @@ -3012,7 +3006,7 @@ wasm::IonCompileFunction(IonCompileTask* task) return false; } - if (IsVoid(f.sig().ret())) + if (IsVoid(f.sig().ret()) || !last) f.returnVoid(); else f.returnExpr(last); diff --git a/js/src/asmjs/WasmIonCompile.h b/js/src/asmjs/WasmIonCompile.h index 5bbbd4b2766..b3d49b2c518 100644 --- a/js/src/asmjs/WasmIonCompile.h +++ b/js/src/asmjs/WasmIonCompile.h @@ -77,7 +77,8 @@ class IonCompileTask IonCompileTask& operator=(const IonCompileTask&) = delete; public: - IonCompileTask(JSRuntime* rt, CompileArgs args, ModuleGeneratorThreadView& mg, size_t defaultChunkSize) + IonCompileTask(JSRuntime* rt, CompileArgs args, ModuleGeneratorThreadView& mg, + size_t defaultChunkSize) : runtime_(rt), args_(args), mg_(mg), diff --git a/js/src/asmjs/WasmText.cpp b/js/src/asmjs/WasmText.cpp index af65f6335e4..d6c7cc9ea7f 100644 --- a/js/src/asmjs/WasmText.cpp +++ b/js/src/asmjs/WasmText.cpp @@ -41,6 +41,8 @@ static const unsigned AST_LIFO_DEFAULT_CHUNK_SIZE = 4096; /*****************************************************************************/ // wasm AST +class WasmAstExpr; + template using WasmAstVector = mozilla::Vector>; @@ -48,6 +50,7 @@ template using WasmAstHashMap = HashMap>; typedef WasmAstVector WasmAstValTypeVector; +typedef WasmAstVector WasmAstExprVector; struct WasmAstBase { @@ -88,6 +91,7 @@ class WasmAstSig : public WasmAstBase enum class WasmAstKind { + Block, Const, Export, Func, @@ -178,6 +182,20 @@ class WasmAstSetLocal : public WasmAstExpr } }; +class WasmAstBlock : public WasmAstExpr +{ + WasmAstExprVector exprs_; + + public: + static const WasmAstKind Kind = WasmAstKind::Block; + WasmAstBlock(WasmAstExprVector&& exprs) + : WasmAstExpr(Kind), + exprs_(Move(exprs)) + {} + + const WasmAstExprVector& exprs() const { return exprs_; } +}; + class WasmAstFunc : public WasmAstNode { const uint32_t sigIndex_; @@ -285,6 +303,7 @@ class WasmToken public: enum Kind { + Block, CloseParen, Const, EndOfFile, @@ -457,6 +476,11 @@ class WasmTokenStream } while (*cur_++ != '"'); return WasmToken(WasmToken::Text, begin, cur_); + case 'b': + if (consume(end_, MOZ_UTF16("lock"))) + return WasmToken(WasmToken::Block, begin, cur_); + break; + case '$': while (cur_ != end_ && IsNameAfterDollar(*cur_)) cur_++; @@ -571,7 +595,7 @@ class WasmTokenStream {} void generateError(WasmToken token, UniqueChars* error) { unsigned column = token.begin() - lineStart_ + 1; - error->reset(JS_smprintf("parsing wasm text at at %u:%u", line_, column)); + error->reset(JS_smprintf("parsing wasm text at %u:%u", line_, column)); } WasmToken peek() { @@ -679,6 +703,27 @@ ParseSetLocal(WasmParseContext& c) return new(c.lifo) WasmAstSetLocal(localIndex.integer(), *value); } +static WasmAstBlock* +ParseBlock(WasmParseContext& c) +{ + WasmToken numExprs; + if (!c.ts.match(WasmToken::Integer, &numExprs, c.error)) + return nullptr; + + WasmAstExprVector exprs(c.lifo); + if (!exprs.reserve(numExprs.integer())) + return nullptr; + + for (uint32_t i = 0; i < numExprs.integer(); i++) { + WasmAstExpr* value = ParseExpr(c); + if (!value) + return nullptr; + exprs.infallibleAppend(value); + } + + return new(c.lifo) WasmAstBlock(Move(exprs)); +} + static WasmAstExpr* ParseExprInsideParens(WasmParseContext& c) { @@ -687,6 +732,8 @@ ParseExprInsideParens(WasmParseContext& c) switch (expr.kind()) { case WasmToken::Nop: return new(c.lifo) WasmAstNop; + case WasmToken::Block: + return ParseBlock(c); case WasmToken::Const: return ParseConst(c, expr); case WasmToken::GetLocal: @@ -850,6 +897,24 @@ TextToAst(const char16_t* text, LifoAlloc& lifo, UniqueChars* error) static bool EncodeExpr(Encoder& e, WasmAstExpr& expr); +static bool +EncodeBlock(Encoder& e, WasmAstBlock& b) +{ + if (!e.writeExpr(Expr::Block)) + return false; + + size_t numExprs = b.exprs().length(); + if (!e.writeVarU32(numExprs)) + return false; + + for (size_t i = 0; i < numExprs; i++) { + if (!EncodeExpr(e, *b.exprs()[i])) + return false; + } + + return true; +} + static bool EncodeConst(Encoder& e, WasmAstConst& c) { @@ -884,6 +949,8 @@ EncodeExpr(Encoder& e, WasmAstExpr& expr) switch (expr.kind()) { case WasmAstKind::Nop: return e.writeExpr(Expr::Nop); + case WasmAstKind::Block: + return EncodeBlock(e, expr.as()); case WasmAstKind::Const: return EncodeConst(e, expr.as()); case WasmAstKind::GetLocal: diff --git a/js/src/jit-test/tests/wasm/basic.js b/js/src/jit-test/tests/wasm/basic.js index fb915b045b2..c6e83923ca8 100644 --- a/js/src/jit-test/tests/wasm/basic.js +++ b/js/src/jit-test/tests/wasm/basic.js @@ -126,3 +126,24 @@ assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (i32. assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (get_local 0))) (export "" 0))')(), 0); assertErrorMessage(() => wasmEvalText('(module (func (local i64)))'), Error, /NYI/); + +// ---------------------------------------------------------------------------- +// blocks + +assertThrowsInstanceOf(() => wasmEvalText('(module (block))'), Error); +assertThrowsInstanceOf(() => wasmEvalText('(module (block -1 (i32.const 42)))'), Error); +assertEq(wasmEvalText('(module (func (block 0)) (export "" 0))')(), undefined); + +assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block 0)))'), Error, mismatchError("void", "i32")); +assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block 1 (block 0))))'), Error, mismatchError("void", "i32")); +assertErrorMessage(() => wasmEvalText('(module (func (local i32) (set_local 0 (block 0))))'), Error, mismatchError("void", "i32")); + +assertThrowsInstanceOf(() => wasmEvalText('(module (block 1))'), Error); +assertEq(wasmEvalText('(module (func (block 1 (block 0))) (export "" 0))')(), undefined); +assertEq(wasmEvalText('(module (func (result i32) (block 1 (i32.const 42))) (export "" 0))')(), 42); +assertEq(wasmEvalText('(module (func (result i32) (block 1 (block 1 (i32.const 42)))) (export "" 0))')(), 42); +assertErrorMessage(() => wasmEvalText('(module (func (result f32) (block 1 (i32.const 0))))'), Error, mismatchError("i32", "f32")); + +assertEq(wasmEvalText('(module (func (result i32) (block 2 (i32.const 13) (block 1 (i32.const 42)))) (export "" 0))')(), 42); +assertErrorMessage(() => wasmEvalText('(module (func (result f32) (param f32) (block 2 (get_local 0) (i32.const 0))))'), Error, mismatchError("i32", "f32")); + From d028fb1648ebe14b4b50d5824792a9d8f3060a0b Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 27 Jan 2016 15:30:08 +0100 Subject: [PATCH 089/218] Bug 1243373: Ensure all declared functions are defined; r=luke --- js/src/asmjs/Wasm.cpp | 3 +++ js/src/jit-test/tests/wasm/binary.js | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/js/src/asmjs/Wasm.cpp b/js/src/asmjs/Wasm.cpp index f903fcfa3a7..2d17d8cb830 100644 --- a/js/src/asmjs/Wasm.cpp +++ b/js/src/asmjs/Wasm.cpp @@ -494,6 +494,9 @@ DecodeCodeSection(JSContext* cx, Decoder& d, ModuleGenerator& mg) return Fail(cx, d, "code section byte size mismatch"); } + if (funcIndex != mg.numFuncSigs()) + return Fail(cx, d, "fewer function definitions than declarations"); + if (!mg.finishFuncDefs()) return false; diff --git a/js/src/jit-test/tests/wasm/binary.js b/js/src/jit-test/tests/wasm/binary.js index 999ee0a237f..262ca9bff57 100644 --- a/js/src/jit-test/tests/wasm/binary.js +++ b/js/src/jit-test/tests/wasm/binary.js @@ -119,4 +119,5 @@ function declSection(decls) { assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([]), declSection([0])]))), Error, /signature index out of range/); assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[], ret:VoidCode}]), declSection([1])]))), Error, /signature index out of range/); -wasmEval(toBuf(moduleWithSections([sigSection([{args:[], ret:VoidCode}]), declSection([0])]))); + +assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[], ret:VoidCode}]), declSection([0])]))), Error, /fewer function definitions than declarations/); From 7e221f007663ecde2160ceb50f95ce40f9ca85e6 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 27 Jan 2016 18:36:16 +0100 Subject: [PATCH 090/218] Bug 1242949: Add explicit keyword to WasmAstBlock ctor; r=bustage --- js/src/asmjs/WasmText.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/asmjs/WasmText.cpp b/js/src/asmjs/WasmText.cpp index d6c7cc9ea7f..03bff2e7e17 100644 --- a/js/src/asmjs/WasmText.cpp +++ b/js/src/asmjs/WasmText.cpp @@ -188,7 +188,7 @@ class WasmAstBlock : public WasmAstExpr public: static const WasmAstKind Kind = WasmAstKind::Block; - WasmAstBlock(WasmAstExprVector&& exprs) + explicit WasmAstBlock(WasmAstExprVector&& exprs) : WasmAstExpr(Kind), exprs_(Move(exprs)) {} From 0096938b094d9876856359c723fbdbbdee0f0d70 Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Fri, 13 Nov 2015 16:22:35 -0800 Subject: [PATCH 091/218] Bug 1237445 - Use GCHashSet for BaseShapeSet and InitialShapeSet, r=terrence --- js/src/vm/Shape.cpp | 32 ++------------------------------ js/src/vm/Shape.h | 16 +++++++++++----- 2 files changed, 13 insertions(+), 35 deletions(-) diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp index dcfcf6d7f99..3de366f8c22 100644 --- a/js/src/vm/Shape.cpp +++ b/js/src/vm/Shape.cpp @@ -1316,18 +1316,7 @@ BaseShape::traceChildren(JSTracer* trc) void JSCompartment::sweepBaseShapeTable() { - if (!baseShapes.initialized()) - return; - - for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) { - UnownedBaseShape* base = e.front().unbarrieredGet(); - if (IsAboutToBeFinalizedUnbarriered(&base)) { - e.removeFront(); - } else if (base != e.front().unbarrieredGet()) { - ReadBarriered b(base); - e.rekeyFront(base, b); - } - } + baseShapes.sweep(); } #ifdef JSGC_HASH_TABLE_CHECKS @@ -1612,24 +1601,7 @@ EmptyShape::insertInitialShape(ExclusiveContext* cx, HandleShape shape, HandleOb void JSCompartment::sweepInitialShapeTable() { - if (initialShapes.initialized()) { - for (InitialShapeSet::Enum e(initialShapes); !e.empty(); e.popFront()) { - const InitialShapeEntry& entry = e.front(); - Shape* shape = entry.shape.unbarrieredGet(); - JSObject* proto = entry.proto.raw(); - if (IsAboutToBeFinalizedUnbarriered(&shape) || - (entry.proto.isObject() && IsAboutToBeFinalizedUnbarriered(&proto))) - { - e.removeFront(); - } else { - if (shape != entry.shape.unbarrieredGet() || proto != entry.proto.raw()) { - ReadBarrieredShape readBarrieredShape(shape); - InitialShapeEntry newKey(readBarrieredShape, TaggedProto(proto)); - e.rekeyFront(newKey.getLookup(), newKey); - } - } - } - } + initialShapes.sweep(); } void diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index 26566e3e6a1..5117dbf2ea2 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -520,10 +520,9 @@ struct StackBaseShape : public DefaultHasher> static inline bool match(ReadBarriered key, const Lookup& lookup); }; -typedef HashSet, - StackBaseShape, - SystemAllocPolicy> BaseShapeSet; - +using BaseShapeSet = js::GCHashSet, + StackBaseShape, + SystemAllocPolicy>; class Shape : public gc::TenuredCell { @@ -1112,9 +1111,16 @@ struct InitialShapeEntry static inline HashNumber hash(const Lookup& lookup); static inline bool match(const InitialShapeEntry& key, const Lookup& lookup); static void rekey(InitialShapeEntry& k, const InitialShapeEntry& newKey) { k = newKey; } + + bool needsSweep() { + Shape* ushape = shape.unbarrieredGet(); + JSObject* protoObj = proto.raw(); + return (gc::IsAboutToBeFinalizedUnbarriered(&ushape) || + (proto.isObject() && gc::IsAboutToBeFinalizedUnbarriered(&protoObj))); + } }; -typedef HashSet InitialShapeSet; +using InitialShapeSet = js::GCHashSet; struct StackShape : public JS::Traceable { From 5f1408fee88eb22c4fb6f93f9bce5d8e8a24a02d Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Tue, 12 Jan 2016 12:55:35 -0800 Subject: [PATCH 092/218] Bug 1237445 - Use GCHashSet for RegExpShared sweeping, r=terrence --- js/src/vm/RegExpObject.cpp | 53 +++++++++++++++++++++----------------- js/src/vm/RegExpObject.h | 1 + 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp index 6e195d124e8..ce9ffaa95f4 100644 --- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -787,6 +787,34 @@ RegExpCompartment::init(JSContext* cx) return true; } +bool +RegExpShared::needsSweep(JSRuntime* rt) +{ + // Sometimes RegExpShared instances are marked without the compartment + // being subsequently cleared. This can happen if a GC is restarted while + // in progress (i.e. performing a full GC in the middle of an incremental + // GC) or if a RegExpShared referenced via the stack is traced but is not + // in a zone being collected. + // + // Because of this we only treat the marked_ bit as a hint, and destroy the + // RegExpShared if it was accidentally marked earlier but wasn't marked by + // the current trace. + bool keep = marked() && IsMarked(&source); + for (size_t i = 0; i < ArrayLength(compilationArray); i++) { + RegExpShared::RegExpCompilation& compilation = compilationArray[i]; + if (compilation.jitCode && gc::IsAboutToBeFinalized(&compilation.jitCode)) + keep = false; + } + + MOZ_ASSERT(rt->isHeapMajorCollecting()); + if (keep || rt->gc.isHeapCompacting()) { + clearMarked(); + return false; + } + + return true; +} + void RegExpCompartment::sweep(JSRuntime* rt) { @@ -795,30 +823,7 @@ RegExpCompartment::sweep(JSRuntime* rt) for (Set::Enum e(set_); !e.empty(); e.popFront()) { RegExpShared* shared = e.front(); - - // Sometimes RegExpShared instances are marked without the - // compartment being subsequently cleared. This can happen if a GC is - // restarted while in progress (i.e. performing a full GC in the - // middle of an incremental GC) or if a RegExpShared referenced via the - // stack is traced but is not in a zone being collected. - // - // Because of this we only treat the marked_ bit as a hint, and destroy - // the RegExpShared if it was accidentally marked earlier but wasn't - // marked by the current trace. - bool keep = shared->marked() && - IsMarked(&shared->source); - for (size_t i = 0; i < ArrayLength(shared->compilationArray); i++) { - RegExpShared::RegExpCompilation& compilation = shared->compilationArray[i]; - if (compilation.jitCode && - IsAboutToBeFinalized(&compilation.jitCode)) - { - keep = false; - } - } - MOZ_ASSERT(rt->isHeapMajorCollecting()); - if (keep || rt->gc.isHeapCompacting()) { - shared->clearMarked(); - } else { + if (shared->needsSweep(rt)) { js_delete(shared); e.removeFront(); } diff --git a/js/src/vm/RegExpObject.h b/js/src/vm/RegExpObject.h index e0eb3b13b1f..0b66d0842b5 100644 --- a/js/src/vm/RegExpObject.h +++ b/js/src/vm/RegExpObject.h @@ -201,6 +201,7 @@ class RegExpShared } void trace(JSTracer* trc); + bool needsSweep(JSRuntime* rt); bool marked() const { return marked_; } void clearMarked() { marked_ = false; } From af51eca272d137995d29860c5047afc1a65b4b6f Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Wed, 20 Jan 2016 09:27:02 -0800 Subject: [PATCH 093/218] Bug 1237445 - Rekey ArrayObjectTable, r=terrence --- js/src/vm/ObjectGroup.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/src/vm/ObjectGroup.h b/js/src/vm/ObjectGroup.h index 5cb3a0d0d65..14b4991443d 100644 --- a/js/src/vm/ObjectGroup.h +++ b/js/src/vm/ObjectGroup.h @@ -547,10 +547,10 @@ class ObjectGroupCompartment NewTable* lazyTable; struct ArrayObjectKey; - using ArrayObjectTable = js::GCHashMap; + using ArrayObjectTable = js::GCRekeyableHashMap; struct PlainObjectKey; struct PlainObjectEntry; From b3eaae199558b5c4cd12f5ae33045b96ed852281 Mon Sep 17 00:00:00 2001 From: George Wright Date: Tue, 26 Jan 2016 17:59:02 -0500 Subject: [PATCH 094/218] Bug 1179732 - Make the tresize addon e10s compatible r=jmaher --- .../talos/talos/startup_test/tresize/addon/content/tresize.js | 4 ++-- testing/talos/talos/startup_test/tresize/addon/install.rdf | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/testing/talos/talos/startup_test/tresize/addon/content/tresize.js b/testing/talos/talos/startup_test/tresize/addon/content/tresize.js index f15e2840c08..6baf654dcf1 100644 --- a/testing/talos/talos/startup_test/tresize/addon/content/tresize.js +++ b/testing/talos/talos/startup_test/tresize/addon/content/tresize.js @@ -16,7 +16,7 @@ var dumpDataSet = false; var doneCallback = null; function painted() { - window.gBrowser.removeEventListener("MozAfterPaint", painted, true); + window.removeEventListener("MozAfterPaint", painted, true); var paintTime = window.performance.now(); Profiler.pause("resize " + count); dataSet[count].end = paintTime; @@ -26,7 +26,7 @@ function painted() { function resizeTest() { try { windowSize += resizeIncrement; - window.gBrowser.addEventListener("MozAfterPaint", painted, true); + window.addEventListener("MozAfterPaint", painted, true); Profiler.resume("resize " + count); dataSet[count] = {'start': window.performance.now()}; window.resizeTo(windowSize,windowSize); diff --git a/testing/talos/talos/startup_test/tresize/addon/install.rdf b/testing/talos/talos/startup_test/tresize/addon/install.rdf index 34b6e8c4ef7..bc37eb46cdc 100644 --- a/testing/talos/talos/startup_test/tresize/addon/install.rdf +++ b/testing/talos/talos/startup_test/tresize/addon/install.rdf @@ -17,4 +17,5 @@ Joel Maher https://wiki.mozilla.org/Buildbot/Talos/Tests https://wiki.mozilla.org/Buildbot/Talos/Tests +true From 3960ae8418c08038790a4ab2eb0077d9636ba1a1 Mon Sep 17 00:00:00 2001 From: George Wright Date: Tue, 26 Jan 2016 18:12:17 -0500 Subject: [PATCH 095/218] Bug 1242450 - Do not display hidden