-
Notifications
You must be signed in to change notification settings - Fork 745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Parser] Fix bug in unreachable fallback logic #6676
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -407,9 +407,12 @@ struct IRBuilder::ChildPopper | |
--stackTupleIndex; | ||
} else { | ||
if (stackIndex == 0) { | ||
// No more available values. This is fine iff we are reaching past | ||
// an unreachable. Any error will be caught later when we are | ||
// popping. | ||
// No more available values. This is valid iff we are reaching past | ||
// an unreachable, but we still need the fallback behavior to ensure | ||
// the input unreachable instruction is executed first. If we are | ||
// not reaching past an unreachable, the error will be caught when | ||
// we pop. | ||
needUnreachableFallback = true; | ||
goto pop; | ||
} | ||
--stackIndex; | ||
|
@@ -458,18 +461,20 @@ struct IRBuilder::ChildPopper | |
// We have checked all the constraints, so we are ready to pop children. | ||
for (int i = children.size() - 1; i >= 0; --i) { | ||
if (needUnreachableFallback && | ||
scope.exprStack.size() == *unreachableIndex + 1) { | ||
// The expressions remaining on the stack may be executed, but they do | ||
// not satisfy the requirements to be children of the current parent. | ||
// Explicitly drop them so they will still be executed for their side | ||
// effects and so the remaining children will be filled with | ||
// unreachables. | ||
assert(scope.exprStack.back()->type == Type::unreachable); | ||
for (auto& expr : scope.exprStack) { | ||
expr = Builder(builder.wasm).dropIfConcretelyTyped(expr); | ||
} | ||
scope.exprStack.size() == *unreachableIndex + 1 && i > 0) { | ||
// The next item on the stack is the unreachable instruction we must | ||
// not pop past. We cannot insert unreachables in front of it because | ||
// it might be a branch we actually have to execute, so this next item | ||
// must be child 0. But we are not ready to pop child 0 yet, so | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am having a hard time following this. "The next item is the unreachable we must not pop past" fits There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That helps, thanks. But if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because inside this condition we are not popping a value from the stack, we are synthesizing an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. Ok, I think I understand the surrounding code a bit better now. But I am still quite confused 😄 Specifically, about this sentence:
I can't follow the inference of "so". I can try to paraphrase the key part of it as "We can't insert unreachables, as it might be a branch, and therefore it must be child 0". Neither "we can't insert unreachables" nor "it might be a branch" suggest to me any reason why the child must be 0 and not any other index. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we put the unreachable instruction from the stack in the child 1 slot, then there would be nothing valid to do for the child 0 slot. Popping off the stack would be popping past the unreachable, which we determined we cannot do. Synthesizing an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is that not a problem for the child 2 slot as well? If we put the unreachable instruction from the stack in the child 2 slot then there would be nothing to do for the child 1 or child 0 slots, I think, for the exact reasons you said? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly, it's a problem for any slot except for child 0. That's why the child 0 slot is special. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see now, thanks... sorry for being dense! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Haha no worries! It's certainly a dense piece of code. |
||
// synthesize an unreachable instead of popping. The deeper | ||
// instructions that would otherwise have been popped will remain on | ||
// the stack to become prior children of future expressions or to be | ||
// implicitly dropped at the end of the scope. | ||
*children[i].childp = builder.builder.makeUnreachable(); | ||
continue; | ||
} | ||
|
||
// Pop a child normally. | ||
auto val = pop(children[i].constraint.size()); | ||
CHECK_ERR(val); | ||
*children[i].childp = *val; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to change the meaning of
needUnreachableFallback
slightly - worth updating the comment on line 379 perhaps?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That comment is actually already correct because it mentions "or try to pop from an empty stack." This fixes the code to agree with the comment.