(&mut self, targets: BrTable<'a>)
| 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 | }; |
nothing calls this directly
no test coverage detected