diff --git a/cranelift/wasmtests/br_table.wat b/cranelift/wasmtests/br_table.wat new file mode 100644 index 0000000000..75444fa49c --- /dev/null +++ b/cranelift/wasmtests/br_table.wat @@ -0,0 +1,30 @@ +(module + (func (result i32) + (block (result i32) + (block (result i32) + (block (result i32) + (br_table 0 1 2 3 (i32.const 42) (i32.const 0)) + ) + ) + ) + ) + (func (result i32) + (block (result i32) + (block (result i32) + (block (result i32) + (br_table 3 2 1 0 (i32.const 42) (i32.const 0)) + ) + ) + ) + ) + (func (result i32) + (block (result i32) + (br_table 0 0 1 1 (i32.const 42) (i32.const 0)) + ) + ) + (func (result i32) + (block (result i32) + (br_table 1 1 0 0 (i32.const 42) (i32.const 0)) + ) + ) +) diff --git a/lib/wasm/src/code_translator.rs b/lib/wasm/src/code_translator.rs index e7a62b65fe..8d5fee979a 100644 --- a/lib/wasm/src/code_translator.rs +++ b/lib/wasm/src/code_translator.rs @@ -307,15 +307,16 @@ pub fn translate_operator( }; data.push_entry(branch_ebb); } - let jt = builder.create_jump_table(data); - let default_ebb = { - let i = state.control_stack.len() - 1 - (default as usize); - let frame = &mut state.control_stack[i]; - frame.set_branched_to_exit(); - frame.br_destination() + let default_branch_ebb = match dest_ebb_map.entry(default as usize) { + hash_map::Entry::Occupied(entry) => *entry.get(), + hash_map::Entry::Vacant(entry) => { + let ebb = builder.create_ebb(); + dest_ebb_sequence.push((default as usize, ebb)); + *entry.insert(ebb) + } }; - dest_ebb_sequence.push((default as usize, default_ebb)); - builder.ins().br_table(val, default_ebb, jt); + let jt = builder.create_jump_table(data); + builder.ins().br_table(val, default_branch_ebb, jt); for (depth, dest_ebb) in dest_ebb_sequence { builder.switch_to_block(dest_ebb); builder.seal_block(dest_ebb);