The terminator that we need to insert has already been picked ahead of time we just need to build the instructions for it
(
&mut self,
builder: &mut FunctionBuilder,
source_block: Block,
)
| 1476 | /// The terminator that we need to insert has already been picked ahead of time |
| 1477 | /// we just need to build the instructions for it |
| 1478 | fn insert_terminator( |
| 1479 | &mut self, |
| 1480 | builder: &mut FunctionBuilder, |
| 1481 | source_block: Block, |
| 1482 | ) -> Result<()> { |
| 1483 | let terminator = self.resources.block_terminators[source_block.as_u32() as usize].clone(); |
| 1484 | |
| 1485 | match terminator { |
| 1486 | BlockTerminator::Return => { |
| 1487 | let types: Vec<Type> = { |
| 1488 | let rets = &builder.func.signature.returns; |
| 1489 | rets.iter().map(|p| p.value_type).collect() |
| 1490 | }; |
| 1491 | let vals = self.generate_values_for_signature(builder, types.into_iter())?; |
| 1492 | |
| 1493 | builder.ins().return_(&vals[..]); |
| 1494 | } |
| 1495 | BlockTerminator::Jump(target) => { |
| 1496 | let args = self.generate_values_for_block(builder, target)?; |
| 1497 | builder.ins().jump(target, &args[..]); |
| 1498 | } |
| 1499 | BlockTerminator::Br(left, right) => { |
| 1500 | let left_args = self.generate_values_for_block(builder, left)?; |
| 1501 | let right_args = self.generate_values_for_block(builder, right)?; |
| 1502 | |
| 1503 | let condbr_types = [I8, I16, I32, I64, I128]; |
| 1504 | let _type = *self.u.choose(&condbr_types[..])?; |
| 1505 | let val = builder.use_var(self.get_variable_of_type(_type)?); |
| 1506 | builder |
| 1507 | .ins() |
| 1508 | .brif(val, left, &left_args[..], right, &right_args[..]); |
| 1509 | } |
| 1510 | BlockTerminator::BrTable(default, targets) => { |
| 1511 | // Create jump tables on demand |
| 1512 | let mut jt = Vec::with_capacity(targets.len()); |
| 1513 | for block in targets { |
| 1514 | let args = self.generate_values_for_block(builder, block)?; |
| 1515 | jt.push(builder.func.dfg.block_call(block, &args)) |
| 1516 | } |
| 1517 | |
| 1518 | let args = self.generate_values_for_block(builder, default)?; |
| 1519 | let jt_data = JumpTableData::new(builder.func.dfg.block_call(default, &args), &jt); |
| 1520 | let jt = builder.create_jump_table(jt_data); |
| 1521 | |
| 1522 | // br_table only supports I32 |
| 1523 | let val = builder.use_var(self.get_variable_of_type(I32)?); |
| 1524 | |
| 1525 | builder.ins().br_table(val, jt); |
| 1526 | } |
| 1527 | BlockTerminator::Switch(_type, default, entries) => { |
| 1528 | let mut switch = Switch::new(); |
| 1529 | for (&entry, &block) in entries.iter() { |
| 1530 | switch.set_entry(entry, block); |
| 1531 | } |
| 1532 | |
| 1533 | let switch_val = builder.use_var(self.get_variable_of_type(_type)?); |
| 1534 | |
| 1535 | switch.emit(builder, switch_val, default); |
no test coverage detected