(
bx: &mut FunctionBuilder,
val: Value,
otherwise: Block,
first_index: EntryIndex,
blocks: &[Block],
)
| 199 | } |
| 200 | |
| 201 | fn build_jump_table( |
| 202 | bx: &mut FunctionBuilder, |
| 203 | val: Value, |
| 204 | otherwise: Block, |
| 205 | first_index: EntryIndex, |
| 206 | blocks: &[Block], |
| 207 | ) { |
| 208 | // There are currently no 128bit systems supported by rustc, but once we do ensure that |
| 209 | // we don't silently ignore a part of the jump table for 128bit integers on 128bit systems. |
| 210 | assert!( |
| 211 | u32::try_from(blocks.len()).is_ok(), |
| 212 | "Jump tables bigger than 2^32-1 are not yet supported" |
| 213 | ); |
| 214 | |
| 215 | let jt_data = JumpTableData::new( |
| 216 | bx.func.dfg.block_call(otherwise, &[]), |
| 217 | &blocks |
| 218 | .iter() |
| 219 | .map(|block| bx.func.dfg.block_call(*block, &[])) |
| 220 | .collect::<Vec<_>>(), |
| 221 | ); |
| 222 | let jump_table = bx.create_jump_table(jt_data); |
| 223 | |
| 224 | let discr = if first_index == 0 { |
| 225 | val |
| 226 | } else { |
| 227 | if let Ok(first_index) = u64::try_from(first_index) { |
| 228 | bx.ins().iadd_imm(val, (first_index as i64).wrapping_neg()) |
| 229 | } else { |
| 230 | let (lsb, msb) = (first_index as u64, (first_index >> 64) as u64); |
| 231 | let lsb = bx.ins().iconst(types::I64, lsb as i64); |
| 232 | let msb = bx.ins().iconst(types::I64, msb as i64); |
| 233 | let index = bx.ins().iconcat(lsb, msb); |
| 234 | bx.ins().isub(val, index) |
| 235 | } |
| 236 | }; |
| 237 | |
| 238 | let discr = match bx.func.dfg.value_type(discr).bits() { |
| 239 | bits if bits > 32 => { |
| 240 | // Check for overflow of cast to u32. This is the max supported jump table entries. |
| 241 | let new_block = bx.create_block(); |
| 242 | let bigger_than_u32 = |
| 243 | bx.ins() |
| 244 | .icmp_imm(IntCC::UnsignedGreaterThan, discr, u32::MAX as i64); |
| 245 | bx.ins() |
| 246 | .brif(bigger_than_u32, otherwise, &[], new_block, &[]); |
| 247 | bx.seal_block(new_block); |
| 248 | bx.switch_to_block(new_block); |
| 249 | |
| 250 | // Cast to i32, as br_table is not implemented for i64/i128 |
| 251 | bx.ins().ireduce(types::I32, discr) |
| 252 | } |
| 253 | bits if bits < 32 => bx.ins().uextend(types::I32, discr), |
| 254 | _ => discr, |
| 255 | }; |
| 256 | |
| 257 | bx.ins().br_table(discr, jump_table); |
| 258 | } |
nothing calls this directly
no test coverage detected