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

Method visit_br_table

winch/codegen/src/visitor.rs:1933–2029  ·  view source on GitHub ↗
(&mut self, targets: BrTable<'a>)

Source from the content-addressed store, hash-verified

1931 }
1932
1933 fn visit_br_table(&mut self, targets: BrTable<'a>) -> Self::Output {
1934 // +1 to account for the default target.
1935 let len = targets.len() + 1;
1936 // SmallVec<[_; 5]> to match the binary emission layer (e.g
1937 // see `JmpTableSeq'), but here we use 5 instead since we
1938 // bundle the default target as the last element in the array.
1939 let mut labels: SmallVec<[_; 5]> = smallvec![];
1940 for _ in 0..len {
1941 labels.push(self.masm.get_label()?);
1942 }
1943
1944 // Find the innermost target and use it as the relative frame
1945 // for result handling below.
1946 //
1947 // This approach ensures that
1948 // 1. The stack pointer offset is correctly positioned
1949 // according to the expectations of the innermost block end
1950 // sequence.
1951 // 2. We meet the jump site invariants introduced by
1952 // `CodegenContext::br`, which take advantage of Wasm
1953 // semantics given that all jumps are "outward".
1954 let mut innermost = targets.default();
1955 for target in targets.targets() {
1956 let target = target?;
1957 if target < innermost {
1958 innermost = target;
1959 }
1960 }
1961
1962 let innermost_index = control_index(innermost, self.control_frames.len())?;
1963 let innermost_frame = &mut self.control_frames[innermost_index];
1964 let innermost_result = innermost_frame.results::<M>()?;
1965
1966 let (index, tmp) = {
1967 let index_and_tmp = self.context.without::<Result<(TypedReg, _)>, M, _>(
1968 innermost_result.regs(),
1969 self.masm,
1970 |cx, masm| Ok((cx.pop_to_reg(masm, None)?, cx.any_gpr(masm)?)),
1971 )??;
1972
1973 // Materialize any constants or locals into their result
1974 // representation, so that when reachability is restored,
1975 // they are correctly located. NB: the results are popped
1976 // in function of the innermost branch specified for
1977 // `br_table`, which implies that the machine stack will
1978 // be correctly balanced, by virtue of calling
1979 // `pop_abi_results`.
1980
1981 // It's possible that we need to balance the stack for the
1982 // rest of the targets, which will be done before emitting
1983 // the unconditional jump below.
1984 innermost_frame.pop_abi_results::<M, _>(
1985 &mut self.context,
1986 self.masm,
1987 |results, _, _| Ok(results.ret_area().copied()),
1988 )?;
1989 index_and_tmp
1990 };

Callers

nothing calls this directly

Calls 15

control_indexFunction · 0.85
OkFunction · 0.85
pop_to_regMethod · 0.80
any_gprMethod · 0.80
copiedMethod · 0.80
ret_areaMethod · 0.80
chainMethod · 0.80
free_regMethod · 0.80
lenMethod · 0.45
pushMethod · 0.45
get_labelMethod · 0.45
defaultMethod · 0.45

Tested by

no test coverage detected