Wasm translation bugfix: properly clean up value stack for else-branch when if-branch ends in unreachable.
The Wasm translation handles unreachable code sections specially, skipping ops until the end of a block and a control-flow merger at which code becomes reachable again. Unfortunately, while the ordinary else-op handler properly sets up the value stack for the else-branch with the parameters to the if/else, the unreachable-case else-op handler did not. This resulted in a bad translation and CLIF type error despite valid Wasm. Found via fuzzing by :decoder in https://bugzilla.mozilla.org/show_bug.cgi?id=1657895.
This commit is contained in:
@@ -1888,13 +1888,21 @@ fn translate_unreachable_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let (params, _results) =
|
||||
blocktype_params_results(module_translation_state, blocktype)?;
|
||||
let else_block = block_with_params(builder, params, environ)?;
|
||||
state.stack.truncate(
|
||||
state.control_stack.last().unwrap().original_stack_size(),
|
||||
);
|
||||
|
||||
// We change the target of the branch instruction.
|
||||
builder.change_jump_destination(branch_inst, else_block);
|
||||
builder.seal_block(else_block);
|
||||
else_block
|
||||
}
|
||||
ElseData::WithElse { else_block } => else_block,
|
||||
ElseData::WithElse { else_block } => {
|
||||
state.stack.truncate(
|
||||
state.control_stack.last().unwrap().original_stack_size(),
|
||||
);
|
||||
else_block
|
||||
}
|
||||
};
|
||||
|
||||
builder.switch_to_block(else_block);
|
||||
|
||||
Reference in New Issue
Block a user