MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / build_jump_table

Method build_jump_table

cranelift/frontend/src/switch.rs:201–258  ·  view source on GitHub ↗
(
        bx: &mut FunctionBuilder,
        val: Value,
        otherwise: Block,
        first_index: EntryIndex,
        blocks: &[Block],
    )

Source from the content-addressed store, hash-verified

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 }

Callers

nothing calls this directly

Calls 12

block_callMethod · 0.80
wrapping_negMethod · 0.80
create_blockMethod · 0.80
switch_to_blockMethod · 0.80
newFunction · 0.50
mapMethod · 0.45
iterMethod · 0.45
create_jump_tableMethod · 0.45
insMethod · 0.45
bitsMethod · 0.45
value_typeMethod · 0.45
seal_blockMethod · 0.45

Tested by

no test coverage detected