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

Method emit_table_copy

winch/codegen/src/codegen/mod.rs:899–1058  ·  view source on GitHub ↗

Emit the `table.copy` operation.

(&mut self, dst_table: TableIndex, src_table: TableIndex)

Source from the content-addressed store, hash-verified

897
898 /// Emit the `table.copy` operation.
899 pub fn emit_table_copy(&mut self, dst_table: TableIndex, src_table: TableIndex) -> Result<()> {
900 let dst_data = self.env.resolve_table_data(dst_table);
901 let src_data = self.env.resolve_table_data(src_table);
902
903 // The value stack contains `[dst, src, len]` (top is `len`).
904 let len = self.context.pop_to_reg(self.masm, None)?;
905 let src = self.context.pop_to_reg(self.masm, None)?;
906 let dst = self.context.pop_to_reg(self.masm, None)?;
907
908 // Zero-extend each operand to a full 64-bit value so that the
909 // arithmetic and bounds checks below can uniformly operate on 64-bit
910 // quantities regardless of the table's index type.
911 for op in [&len, &src, &dst] {
912 if op.ty == WasmValType::I32 {
913 self.masm.extend(
914 writable!(op.reg),
915 op.reg,
916 Extend::<Zero>::I64Extend32.into(),
917 )?;
918 }
919 }
920
921 // Bounds check both ranges up-front; `table.copy` traps without
922 // copying anything if either range is out-of-bounds.
923 self.emit_table_range_bounds_check(&src_data, src.reg, len.reg)?;
924 self.emit_table_range_bounds_check(&dst_data, dst.reg, len.reg)?;
925
926 // Decide the copy direction. If `dst <= src` then do a forwards copy
927 // and otherwise it's backwards.
928 let step = self.context.any_gpr(self.masm)?;
929 let forward = self.masm.get_label()?;
930 let setup_done = self.masm.get_label()?;
931 self.masm.branch(
932 IntCmpKind::LeU,
933 dst.reg,
934 src.reg.into(),
935 forward,
936 OperandSize::S64,
937 )?;
938 // Backwards: start at the last element and walk down.
939 {
940 self.masm
941 .mov(writable!(step), RegImm::i64(-1), OperandSize::S64)?;
942 self.masm.add(
943 writable!(src.reg),
944 src.reg,
945 len.reg.into(),
946 OperandSize::S64,
947 )?;
948 self.masm.sub(
949 writable!(src.reg),
950 src.reg,
951 RegImm::i64(1),
952 OperandSize::S64,
953 )?;
954 self.masm.add(
955 writable!(dst.reg),
956 dst.reg,

Callers 1

visit_table_copyMethod · 0.80

Calls 15

i64Function · 0.85
OkFunction · 0.85
resolve_table_dataMethod · 0.80
pop_to_regMethod · 0.80
any_gprMethod · 0.80
emit_table_getMethod · 0.80
free_regMethod · 0.80
extendMethod · 0.45
get_labelMethod · 0.45
branchMethod · 0.45
movMethod · 0.45

Tested by

no test coverage detected