Don't special-case br_table with an empty table.
Empty br_table tables are very uncommon (they're easy for wasm producers to optimize away), so we don't need to special-case them.
This commit is contained in:
@@ -523,17 +523,15 @@ fn translate_operator(op: &Operator,
|
|||||||
if jump_args_count == 0 {
|
if jump_args_count == 0 {
|
||||||
// No jump arguments
|
// No jump arguments
|
||||||
let val = stack.pop().unwrap();
|
let val = stack.pop().unwrap();
|
||||||
if depths.len() > 0 {
|
let jt = builder.create_jump_table();
|
||||||
let jt = builder.create_jump_table();
|
for (index, depth) in depths.iter().enumerate() {
|
||||||
for (index, depth) in depths.iter().enumerate() {
|
let i = control_stack.len() - 1 - (*depth as usize);
|
||||||
let i = control_stack.len() - 1 - (*depth as usize);
|
let frame = &mut control_stack[i];
|
||||||
let frame = &mut control_stack[i];
|
let ebb = frame.br_destination();
|
||||||
let ebb = frame.br_destination();
|
builder.insert_jump_table_entry(jt, index, ebb);
|
||||||
builder.insert_jump_table_entry(jt, index, ebb);
|
frame.set_reachable();
|
||||||
frame.set_reachable();
|
|
||||||
}
|
|
||||||
builder.ins().br_table(val, jt);
|
|
||||||
}
|
}
|
||||||
|
builder.ins().br_table(val, jt);
|
||||||
let i = control_stack.len() - 1 - (default as usize);
|
let i = control_stack.len() - 1 - (default as usize);
|
||||||
let frame = &mut control_stack[i];
|
let frame = &mut control_stack[i];
|
||||||
let ebb = frame.br_destination();
|
let ebb = frame.br_destination();
|
||||||
@@ -546,44 +544,36 @@ fn translate_operator(op: &Operator,
|
|||||||
let val = stack.pop().unwrap();
|
let val = stack.pop().unwrap();
|
||||||
let cut_index = stack.len() - jump_args_count;
|
let cut_index = stack.len() - jump_args_count;
|
||||||
let jump_args = stack.split_off(cut_index);
|
let jump_args = stack.split_off(cut_index);
|
||||||
if depths.len() > 0 {
|
let jt = builder.create_jump_table();
|
||||||
let jt = builder.create_jump_table();
|
let dest_ebbs: HashMap<usize, Ebb> = depths
|
||||||
let dest_ebbs: HashMap<usize, Ebb> = depths
|
.iter()
|
||||||
.iter()
|
.enumerate()
|
||||||
.enumerate()
|
.fold(HashMap::new(), |mut acc, (index, &depth)| {
|
||||||
.fold(HashMap::new(), |mut acc, (index, &depth)| {
|
if acc.get(&(depth as usize)).is_none() {
|
||||||
if acc.get(&(depth as usize)).is_none() {
|
let branch_ebb = builder.create_ebb();
|
||||||
let branch_ebb = builder.create_ebb();
|
|
||||||
builder.insert_jump_table_entry(jt, index, branch_ebb);
|
|
||||||
acc.insert(depth as usize, branch_ebb);
|
|
||||||
return acc;
|
|
||||||
};
|
|
||||||
let branch_ebb = acc.get(&(depth as usize)).unwrap().clone();
|
|
||||||
builder.insert_jump_table_entry(jt, index, branch_ebb);
|
builder.insert_jump_table_entry(jt, index, branch_ebb);
|
||||||
acc
|
acc.insert(depth as usize, branch_ebb);
|
||||||
});
|
return acc;
|
||||||
builder.ins().br_table(val, jt);
|
};
|
||||||
let default_ebb = control_stack[control_stack.len() - 1 - (default as usize)]
|
let branch_ebb = acc.get(&(depth as usize)).unwrap().clone();
|
||||||
.br_destination();
|
builder.insert_jump_table_entry(jt, index, branch_ebb);
|
||||||
builder.ins().jump(default_ebb, jump_args.as_slice());
|
acc
|
||||||
stack.extend(jump_args.clone());
|
});
|
||||||
for (depth, dest_ebb) in dest_ebbs {
|
builder.ins().br_table(val, jt);
|
||||||
builder.switch_to_block(dest_ebb, &[]);
|
let default_ebb = control_stack[control_stack.len() - 1 - (default as usize)]
|
||||||
builder.seal_block(dest_ebb);
|
.br_destination();
|
||||||
let i = control_stack.len() - 1 - (depth as usize);
|
builder.ins().jump(default_ebb, jump_args.as_slice());
|
||||||
let frame = &mut control_stack[i];
|
stack.extend(jump_args.clone());
|
||||||
let real_dest_ebb = frame.br_destination();
|
for (depth, dest_ebb) in dest_ebbs {
|
||||||
builder.ins().jump(real_dest_ebb, jump_args.as_slice());
|
builder.switch_to_block(dest_ebb, &[]);
|
||||||
frame.set_reachable();
|
builder.seal_block(dest_ebb);
|
||||||
}
|
let i = control_stack.len() - 1 - (depth as usize);
|
||||||
state.real_unreachable_stack_depth = 1 + min_depth as usize;
|
let frame = &mut control_stack[i];
|
||||||
} else {
|
let real_dest_ebb = frame.br_destination();
|
||||||
let ebb = control_stack[control_stack.len() - 1 - (default as usize)]
|
builder.ins().jump(real_dest_ebb, jump_args.as_slice());
|
||||||
.br_destination();
|
frame.set_reachable();
|
||||||
builder.ins().jump(ebb, jump_args.as_slice());
|
|
||||||
stack.extend(jump_args);
|
|
||||||
state.real_unreachable_stack_depth = 1 + min_depth as usize;
|
|
||||||
}
|
}
|
||||||
|
state.real_unreachable_stack_depth = 1 + min_depth as usize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Operator::Return => {
|
Operator::Return => {
|
||||||
|
|||||||
Reference in New Issue
Block a user