MCPcopy Create free account
hub / github.com/explodingcamera/tinywasm / visit_br_table

Method visit_br_table

crates/parser/src/visit.rs:349–404  ·  view source on GitHub ↗
(&mut self, targets: wasmparser::BrTable<'_>)

Source from the content-addressed store, hash-verified

347 }
348
349 fn visit_br_table(&mut self, targets: wasmparser::BrTable<'_>) -> Self::Output {
350 let ts = targets
351 .targets()
352 .collect::<Result<Vec<_>, wasmparser::BinaryReaderError>>()
353 .expect("visit_br_table: BrTable targets are invalid");
354
355 let default_depth = targets.default();
356 let len = ts.len() as u32;
357 let target_depths: Vec<u32> = ts;
358
359 let header_ip = self.instructions.len();
360 let branch_table_start = self.data.branch_table_targets.len() as u32;
361 self.instructions.push(Instruction::BranchTable(0, branch_table_start, len));
362
363 struct PadInfo {
364 depth: u32,
365 pad_start: usize,
366 jump_or_ret_ip: usize,
367 is_return: bool,
368 }
369 let mut seen = Vec::<(u32, usize)>::new();
370 let mut pads: Vec<PadInfo> = Vec::new();
371
372 for &depth in target_depths.iter().chain(core::iter::once(&default_depth)) {
373 if seen.iter().any(|&(seen_depth, _)| seen_depth == depth) {
374 continue;
375 }
376 seen.push((depth, pads.len()));
377
378 let (pad_start, jump_or_ret_ip, is_return) = self.emit_br_table_pad(depth);
379 pads.push(PadInfo { depth, pad_start, jump_or_ret_ip, is_return });
380 }
381
382 for &depth in &target_depths {
383 let pad_idx = seen
384 .iter()
385 .find_map(|&(seen_depth, idx)| (seen_depth == depth).then_some(idx))
386 .expect("visit_br_table: missing branch table target");
387 self.data.branch_table_targets.push(pads[pad_idx].pad_start as u32);
388 }
389
390 let default_pad_idx = seen
391 .iter()
392 .find_map(|&(seen_depth, idx)| (seen_depth == default_depth).then_some(idx))
393 .expect("visit_br_table: missing default branch table target");
394 if let Instruction::BranchTable(default_ip, _, _) = &mut self.instructions[header_ip] {
395 *default_ip = pads[default_pad_idx].pad_start as u32;
396 }
397
398 for pad in &pads {
399 if pad.is_return {
400 continue;
401 }
402 self.patch_branch_jump_or_return(pad.depth, pad.jump_or_ret_ip);
403 }
404 }
405
406 fn visit_f32_const(&mut self, val: wasmparser::Ieee32) -> Self::Output {

Callers

nothing calls this directly

Calls 5

emit_br_table_padMethod · 0.80
defaultMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected