Emits a bounds check for the range `[idx, idx + len)` against the current size of `table_data`, trapping with `TRAP_TABLE_OUT_OF_BOUNDS` if the range is out-of-bounds. Both `idx` and `len` are expected to be 64-bit values.
(
&mut self,
table_data: &TableData,
idx: Reg,
len: Reg,
)
| 866 | /// |
| 867 | /// Both `idx` and `len` are expected to be 64-bit values. |
| 868 | fn emit_table_range_bounds_check( |
| 869 | &mut self, |
| 870 | table_data: &TableData, |
| 871 | idx: Reg, |
| 872 | len: Reg, |
| 873 | ) -> Result<()> { |
| 874 | self.emit_compute_table_size(table_data)?; |
| 875 | let size = self.context.pop_to_reg(self.masm, None)?; |
| 876 | |
| 877 | // Compute `end = idx + len`, trapping on overflow, and then trap if |
| 878 | // `end > size`. |
| 879 | let end = self.context.any_gpr(self.masm)?; |
| 880 | self.masm |
| 881 | .mov(writable!(end), idx.into(), OperandSize::S64)?; |
| 882 | self.masm.checked_uadd( |
| 883 | writable!(end), |
| 884 | end, |
| 885 | len.into(), |
| 886 | OperandSize::S64, |
| 887 | TRAP_TABLE_OUT_OF_BOUNDS, |
| 888 | )?; |
| 889 | self.masm.cmp(end, size.reg.into(), OperandSize::S64)?; |
| 890 | self.masm |
| 891 | .trapif(IntCmpKind::GtU, TRAP_TABLE_OUT_OF_BOUNDS)?; |
| 892 | |
| 893 | self.context.free_reg(size); |
| 894 | self.context.free_reg(end); |
| 895 | Ok(()) |
| 896 | } |
| 897 | |
| 898 | /// Emit the `table.copy` operation. |
| 899 | pub fn emit_table_copy(&mut self, dst_table: TableIndex, src_table: TableIndex) -> Result<()> { |
no test coverage detected