Merge pull request #2194 from bnjbvr/wasm-multivalue-truncate-after-if

wasm: Remove duplicated parameters when popping an If
This commit is contained in:
Nick Fitzgerald
2020-09-11 08:34:26 -07:00
committed by GitHub
2 changed files with 47 additions and 1 deletions

View File

@@ -323,13 +323,33 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
// since we truncate the stack back to the original height
// below.
}
builder.switch_to_block(next_block);
builder.seal_block(next_block);
// If it is a loop we also have to seal the body loop block
if let ControlStackFrame::Loop { header, .. } = frame {
builder.seal_block(header)
}
state.stack.truncate(frame.original_stack_size());
// The "If" frame pushes its parameters twice, so they're available to the else block
// (see also `FuncTranslationState::push_if`).
// Yet, the original_stack_size member accounts for them only once, so that the else
// block can see the same number of parameters as the consequent block. As a matter of
// fact, we need to substract an extra number of parameter values for if blocks.
let num_duplicated_params = if let ControlStackFrame::If {
num_param_values, ..
} = frame
{
debug_assert!(num_param_values <= frame.original_stack_size());
num_param_values
} else {
0
};
state
.stack
.truncate(frame.original_stack_size() - num_duplicated_params);
state
.stack
.extend_from_slice(builder.block_params(next_block));

View File

@@ -0,0 +1,26 @@
(module
(func $main (type 0) (param i32 i32 i32) (result i32)
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
if (param i32 i32 i32) (result i32) ;; label = @1
br 0 (;@1;)
else
call $main
end
i32.const 0
i32.const 0
if (param i32 i32 i32) (result i32) ;; label = @1
drop
drop
else
drop
drop
end
)
(export "main" (func $main)))