Bug 1668387 - Make nsContainerFrame::StealFrame() return void since it shouldn't fail. r=emilio

The three implementations of StealFrame() -- nsContainerFrame,
nsBlockFrame, and nsInlineFrame -- all have assertions to guarantee
aChild can be found, so the operation shouldn't fail.

This change shouldn't change behavior at all.

Differential Revision: https://phabricator.services.mozilla.com/D91996
This commit is contained in:
Ting-Yu Lin 2020-09-30 23:38:41 +00:00
Родитель 6edb2ee215
Коммит 4041fe929c
7 изменённых файлов: 50 добавлений и 68 удалений

Просмотреть файл

@ -402,8 +402,7 @@ void BlockReflowInput::AppendPushedFloatChain(nsIFrame* aFloatCont) {
if (!aFloatCont || aFloatCont->GetParent() != mBlock) {
break;
}
DebugOnly<nsresult> rv = mBlock->StealFrame(aFloatCont);
NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame should succeed");
mBlock->StealFrame(aFloatCont);
}
}
@ -1019,8 +1018,7 @@ void BlockReflowInput::PushFloatPastBreak(nsIFrame* aFloat) {
// Put the float on the pushed floats list, even though it
// isn't actually a continuation.
DebugOnly<nsresult> rv = mBlock->StealFrame(aFloat);
NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame should succeed");
mBlock->StealFrame(aFloat);
AppendPushedFloatChain(aFloat);
mReflowStatus.SetOverflowIncomplete();
}

Просмотреть файл

@ -4018,10 +4018,7 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState,
nsOverflowContinuationTracker::AutoFinish fini(
aState.mOverflowTracker, frame);
nsContainerFrame* parent = nextFrame->GetParent();
nsresult rv = parent->StealFrame(nextFrame);
if (NS_FAILED(rv)) {
return;
}
parent->StealFrame(nextFrame);
if (parent != this) {
ReparentFrame(nextFrame, parent, this);
}
@ -4085,10 +4082,7 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState,
!nextFrame->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER)) {
// It already exists, but as a normal next-in-flow, so we need
// to dig it out of the child lists.
nsresult rv = nextFrame->GetParent()->StealFrame(nextFrame);
if (NS_FAILED(rv)) {
return;
}
nextFrame->GetParent()->StealFrame(nextFrame);
} else if (madeContinuation) {
mFrames.RemoveFrame(nextFrame);
}
@ -4663,8 +4657,7 @@ void nsBlockFrame::SplitFloat(BlockReflowInput& aState, nsIFrame* aFloat,
nsIFrame* nextInFlow = aFloat->GetNextInFlow();
if (nextInFlow) {
nsContainerFrame* oldParent = nextInFlow->GetParent();
DebugOnly<nsresult> rv = oldParent->StealFrame(nextInFlow);
NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame failed");
oldParent->StealFrame(nextInFlow);
if (oldParent != this) {
ReparentFrame(nextInFlow, oldParent, this);
}
@ -6452,16 +6445,16 @@ static bool FindLineFor(nsIFrame* aChild, const nsFrameList& aFrameList,
: FindInlineLineFor(aChild, aFrameList, aBegin, aEnd, aResult);
}
nsresult nsBlockFrame::StealFrame(nsIFrame* aChild) {
void nsBlockFrame::StealFrame(nsIFrame* aChild) {
MOZ_ASSERT(aChild->GetParent() == this);
if (aChild->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) && aChild->IsFloating()) {
RemoveFloat(aChild);
return NS_OK;
return;
}
if (MaybeStealOverflowContainerFrame(aChild)) {
return NS_OK;
return;
}
MOZ_ASSERT(!aChild->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW));
@ -6475,15 +6468,13 @@ nsresult nsBlockFrame::StealFrame(nsIFrame* aChild) {
found = FindLineFor(aChild, overflowLines->mFrames,
overflowLines->mLines.begin(),
overflowLines->mLines.end(), &line);
MOZ_ASSERT(found);
MOZ_ASSERT(found, "Why can't we find aChild in our overflow lines?");
RemoveFrameFromLine(aChild, line, overflowLines->mFrames,
overflowLines->mLines);
if (overflowLines->mLines.empty()) {
DestroyOverflowLines();
}
}
return NS_OK;
}
void nsBlockFrame::RemoveFrameFromLine(nsIFrame* aChild,

Просмотреть файл

@ -328,7 +328,7 @@ class nsBlockFrame : public nsContainerFrame {
*/
bool DrainSelfOverflowList() override;
nsresult StealFrame(nsIFrame* aChild) override;
void StealFrame(nsIFrame* aChild) override;
void DeleteNextInFlowChild(nsIFrame* aNextInFlow,
bool aDeletingEmptyFrames) override;

Просмотреть файл

@ -1378,10 +1378,7 @@ void nsContainerFrame::ReflowOverflowContainerChildren(
this);
} else if (!nif->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER)) {
// used to be a normal next-in-flow; steal it from the child list
nsresult rv = nif->GetParent()->StealFrame(nif);
if (NS_FAILED(rv)) {
return;
}
nif->GetParent()->StealFrame(nif);
}
tracker.Insert(nif, frameStatus);
@ -1442,7 +1439,7 @@ bool nsContainerFrame::MaybeStealOverflowContainerFrame(nsIFrame* aChild) {
return removed;
}
nsresult nsContainerFrame::StealFrame(nsIFrame* aChild) {
void nsContainerFrame::StealFrame(nsIFrame* aChild) {
#ifdef DEBUG
if (!mFrames.ContainsFrame(aChild)) {
nsFrameList* list = GetOverflowFrames();
@ -1458,27 +1455,28 @@ nsresult nsContainerFrame::StealFrame(nsIFrame* aChild) {
}
#endif
bool removed = MaybeStealOverflowContainerFrame(aChild);
if (!removed) {
// NOTE nsColumnSetFrame and nsCanvasFrame have their overflow containers
// on the normal lists so we might get here also if the frame bit
// NS_FRAME_IS_OVERFLOW_CONTAINER is set.
removed = mFrames.StartRemoveFrame(aChild);
if (!removed) {
// We didn't find the child in our principal child list.
// Maybe it's on the overflow list?
nsFrameList* frameList = GetOverflowFrames();
if (frameList) {
removed = frameList->ContinueRemoveFrame(aChild);
if (frameList->IsEmpty()) {
DestroyOverflowList();
}
}
}
if (MaybeStealOverflowContainerFrame(aChild)) {
return;
}
MOZ_ASSERT(removed, "StealFrame: can't find aChild");
return removed ? NS_OK : NS_ERROR_UNEXPECTED;
// NOTE nsColumnSetFrame and nsCanvasFrame have their overflow containers
// on the normal lists so we might get here also if the frame bit
// NS_FRAME_IS_OVERFLOW_CONTAINER is set.
if (mFrames.StartRemoveFrame(aChild)) {
return;
}
// We didn't find the child in our principal child list.
// Maybe it's on the overflow list?
nsFrameList* frameList = GetOverflowFrames();
if (frameList && frameList->ContinueRemoveFrame(aChild)) {
if (frameList->IsEmpty()) {
DestroyOverflowList();
}
return;
}
MOZ_ASSERT_UNREACHABLE("StealFrame: can't find aChild");
}
nsFrameList nsContainerFrame::StealFramesAfter(nsIFrame* aChild) {
@ -1572,8 +1570,7 @@ void nsContainerFrame::DeleteNextInFlowChild(nsIFrame* aNextInFlow,
}
// Take the next-in-flow out of the parent's child list
DebugOnly<nsresult> rv = StealFrame(aNextInFlow);
NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame failure");
StealFrame(aNextInFlow);
#ifdef DEBUG
if (aDeletingEmptyFrames) {
@ -3004,8 +3001,7 @@ nsresult nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont,
NS_ASSERTION(!(mOverflowContList &&
mOverflowContList->ContainsFrame(aOverflowCont)),
"overflow containers out of order");
rv = aOverflowCont->GetParent()->StealFrame(aOverflowCont);
NS_ENSURE_SUCCESS(rv, rv);
aOverflowCont->GetParent()->StealFrame(aOverflowCont);
} else {
aOverflowCont->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
@ -3074,8 +3070,7 @@ nsresult nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont,
(!reparented && f->GetParent() == mParent) ||
(reparented && f->GetParent() != mParent))) {
if (!f->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER)) {
rv = f->GetParent()->StealFrame(f);
NS_ENSURE_SUCCESS(rv, rv);
f->GetParent()->StealFrame(f);
}
Insert(f, aReflowStatus);
}

Просмотреть файл

@ -389,10 +389,14 @@ class nsContainerFrame : public nsSplittableFrame {
* Continuations are not affected. Checks the principal and overflow lists,
* and also the [excess] overflow containers lists if the frame bit
* NS_FRAME_IS_OVERFLOW_CONTAINER is set. It does not check any other lists.
* Returns NS_ERROR_UNEXPECTED if aChild wasn't found on any of the lists
* mentioned above.
* aChild must be in one of the above mentioned lists, or an assertion is
* triggered.
*
* Note: This method can destroy either overflow list or [excess] overflow
* containers list if aChild is the only child in the list. Any pointer to the
* list obtained prior to calling this method shouldn't be used.
*/
virtual nsresult StealFrame(nsIFrame* aChild);
virtual void StealFrame(nsIFrame* aChild);
/**
* Removes the next-siblings of aChild without destroying them and without

Просмотреть файл

@ -178,30 +178,25 @@ void nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot,
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
}
nsresult nsInlineFrame::StealFrame(nsIFrame* aChild) {
void nsInlineFrame::StealFrame(nsIFrame* aChild) {
if (MaybeStealOverflowContainerFrame(aChild)) {
return NS_OK;
return;
}
nsInlineFrame* parent = this;
bool removed = false;
do {
removed = parent->mFrames.StartRemoveFrame(aChild);
if (removed) {
break;
if (parent->mFrames.StartRemoveFrame(aChild)) {
return;
}
// We didn't find the child in our principal child list.
// Maybe it's on the overflow list?
nsFrameList* frameList = parent->GetOverflowFrames();
if (frameList) {
removed = frameList->ContinueRemoveFrame(aChild);
if (frameList && frameList->ContinueRemoveFrame(aChild)) {
if (frameList->IsEmpty()) {
parent->DestroyOverflowList();
}
if (removed) {
break;
}
return;
}
// Due to our "lazy reparenting" optimization 'aChild' might not actually
@ -209,8 +204,7 @@ nsresult nsInlineFrame::StealFrame(nsIFrame* aChild) {
parent = static_cast<nsInlineFrame*>(parent->GetNextInFlow());
} while (parent);
MOZ_ASSERT(removed, "nsInlineFrame::StealFrame: can't find aChild");
return removed ? NS_OK : NS_ERROR_UNEXPECTED;
MOZ_ASSERT_UNREACHABLE("nsInlineFrame::StealFrame: can't find aChild");
}
void nsInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,

Просмотреть файл

@ -69,7 +69,7 @@ class nsInlineFrame : public nsContainerFrame {
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
virtual nsresult StealFrame(nsIFrame* aChild) override;
void StealFrame(nsIFrame* aChild) override;
// nsIHTMLReflow overrides
virtual void AddInlineMinISize(gfxContext* aRenderingContext,