Implementation of `table.init`
(
&mut self,
elem_index: ElemIndex,
table_index: TableIndex,
)
| 1819 | |
| 1820 | /// Implementation of `table.init` |
| 1821 | pub fn emit_table_init( |
| 1822 | &mut self, |
| 1823 | elem_index: ElemIndex, |
| 1824 | table_index: TableIndex, |
| 1825 | ) -> Result<()> { |
| 1826 | let builtin_base = self.env.builtins.passive_elem_segment_base::<M::ABI>()?; |
| 1827 | let builtin_len = self.env.builtins.passive_elem_segment_len::<M::ABI>()?; |
| 1828 | |
| 1829 | // Push the passive segment's length and base onto the stack. |
| 1830 | match self.env.translation.passive_elem_map[elem_index] { |
| 1831 | Some(idx) => { |
| 1832 | self.context.stack.extend([idx.as_u32().try_into()?]); |
| 1833 | FnCall::emit::<M>( |
| 1834 | &mut self.env, |
| 1835 | self.masm, |
| 1836 | &mut self.context, |
| 1837 | Callee::Builtin(builtin_len), |
| 1838 | )?; |
| 1839 | self.context.stack.extend([idx.as_u32().try_into()?]); |
| 1840 | FnCall::emit::<M>( |
| 1841 | &mut self.env, |
| 1842 | self.masm, |
| 1843 | &mut self.context, |
| 1844 | Callee::Builtin(builtin_base), |
| 1845 | )?; |
| 1846 | } |
| 1847 | // Active data segments have 0 length and a null base pointer. |
| 1848 | None => { |
| 1849 | let tmp = self.context.any_gpr(self.masm)?; |
| 1850 | self.masm |
| 1851 | .mov(writable!(tmp), RegImm::i64(0), OperandSize::S64)?; |
| 1852 | self.context |
| 1853 | .stack |
| 1854 | .push(TypedReg::new(WasmValType::I64, tmp).into()); |
| 1855 | |
| 1856 | let tmp = self.context.any_gpr(self.masm)?; |
| 1857 | self.masm |
| 1858 | .mov(writable!(tmp), RegImm::i64(0), OperandSize::S64)?; |
| 1859 | self.context |
| 1860 | .stack |
| 1861 | .push(TypedReg::new(WasmValType::I64, tmp).into()); |
| 1862 | } |
| 1863 | }; |
| 1864 | |
| 1865 | // Push the table's current length onto the stack. |
| 1866 | let table_data = self.env.resolve_table_data(table_index); |
| 1867 | let idx_size = table_data.index_type().try_into()?; |
| 1868 | self.emit_compute_table_size(&table_data)?; |
| 1869 | |
| 1870 | // And now pop off everything we have for this instruction to work with |
| 1871 | // it all below. |
| 1872 | let table_size = self.context.pop_to_reg(self.masm, None)?; |
| 1873 | let segment_base = self.context.pop_to_reg(self.masm, None)?; |
| 1874 | let segment_len = self.context.pop_to_reg(self.masm, None)?; |
| 1875 | let len = self.context.pop_to_reg(self.masm, None)?; |
| 1876 | let segment_off = self.context.pop_to_reg(self.masm, None)?; |
| 1877 | let table_off = self.context.pop_to_reg(self.masm, None)?; |
| 1878 |
no test coverage detected