(
&mut self,
ty: &Type,
cases: impl IntoIterator<Item = Option<&'b Type>>,
)
| 1680 | } |
| 1681 | |
| 1682 | fn lower_variant_arms<'b>( |
| 1683 | &mut self, |
| 1684 | ty: &Type, |
| 1685 | cases: impl IntoIterator<Item = Option<&'b Type>>, |
| 1686 | ) -> Vec<WasmType> { |
| 1687 | use Instruction::*; |
| 1688 | let results = flat_types(self.resolve, ty, None).unwrap(); |
| 1689 | let mut casts = Vec::new(); |
| 1690 | for (i, ty) in cases.into_iter().enumerate() { |
| 1691 | self.push_block(); |
| 1692 | self.emit(&VariantPayloadName); |
| 1693 | let payload_name = self.stack.pop().unwrap(); |
| 1694 | self.emit(&I32Const { val: i as i32 }); |
| 1695 | let mut pushed = 1; |
| 1696 | if let Some(ty) = ty { |
| 1697 | // Using the payload of this block we lower the type to |
| 1698 | // raw wasm values. |
| 1699 | self.stack.push(payload_name); |
| 1700 | self.lower(ty); |
| 1701 | |
| 1702 | // Determine the types of all the wasm values we just |
| 1703 | // pushed, and record how many. If we pushed too few |
| 1704 | // then we'll need to push some zeros after this. |
| 1705 | let temp = flat_types(self.resolve, ty, None).unwrap(); |
| 1706 | pushed += temp.len(); |
| 1707 | |
| 1708 | // For all the types pushed we may need to insert some |
| 1709 | // bitcasts. This will go through and cast everything |
| 1710 | // to the right type to ensure all blocks produce the |
| 1711 | // same set of results. |
| 1712 | casts.truncate(0); |
| 1713 | for (actual, expected) in temp.iter().zip(&results[1..]) { |
| 1714 | casts.push(cast(*actual, *expected)); |
| 1715 | } |
| 1716 | if casts.iter().any(|c| *c != Bitcast::None) { |
| 1717 | self.emit(&Bitcasts { casts: &casts }); |
| 1718 | } |
| 1719 | } |
| 1720 | |
| 1721 | // If we haven't pushed enough items in this block to match |
| 1722 | // what other variants are pushing then we need to push |
| 1723 | // some zeros. |
| 1724 | if pushed < results.len() { |
| 1725 | self.emit(&ConstZero { |
| 1726 | tys: &results[pushed..], |
| 1727 | }); |
| 1728 | } |
| 1729 | self.finish_block(results.len()); |
| 1730 | } |
| 1731 | results |
| 1732 | } |
| 1733 | |
| 1734 | fn list_realloc(&self) -> Option<&'static str> { |
| 1735 | match self.realloc.expect("realloc should be configured") { |
no test coverage detected