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

Method emit_table_fill

winch/codegen/src/codegen/mod.rs:773–861  ·  view source on GitHub ↗

Emit the `table.fill` operation.

(&mut self, table_index: TableIndex)

Source from the content-addressed store, hash-verified

771
772 /// Emit the `table.fill` operation.
773 pub fn emit_table_fill(&mut self, table_index: TableIndex) -> Result<()> {
774 // Put all of this opcode's arguments into registers.
775 let len = self.context.pop_to_reg(self.masm, None)?;
776 let init = self.context.pop_to_reg(self.masm, None)?;
777 let offset = self.context.pop_to_reg(self.masm, None)?;
778
779 // Perform a bounds check to see if `offset+len` is inbounds.
780 let table_data = self.env.resolve_table_data(table_index);
781 self.emit_compute_table_size(&table_data)?;
782 let table_size = self.context.pop_to_reg(self.masm, None)?;
783 let tmp = self.context.any_gpr(self.masm)?;
784 let idx_size = table_data.index_type().try_into()?;
785 self.masm.mov(writable!(tmp), offset.reg.into(), idx_size)?;
786 self.masm.checked_uadd(
787 writable!(tmp),
788 tmp,
789 len.reg.into(),
790 idx_size,
791 TRAP_TABLE_OUT_OF_BOUNDS,
792 )?;
793 self.masm.cmp(tmp, table_size.reg.into(), idx_size)?;
794 self.masm
795 .trapif(IntCmpKind::GtU, TRAP_TABLE_OUT_OF_BOUNDS)?;
796 self.context.free_reg(tmp);
797 self.context.free_reg(table_size);
798
799 let header = self.masm.get_label()?;
800 let exit = self.masm.get_label()?;
801
802 self.masm.bind(header)?;
803
804 // Exit the loop once there are no more elements to copy.
805 self.masm.branch(
806 IntCmpKind::Eq,
807 len.reg,
808 RegImm::i64(0),
809 exit,
810 OperandSize::S64,
811 )?;
812
813 // Duplicate `offset`, where we're writing, and `init` what we're
814 // writing, into temporary registers. These are used by `emit_table_set`
815 // below.
816 let tmp_index = self.context.any_gpr(self.masm)?;
817 let tmp_init = self.context.any_gpr(self.masm)?;
818 self.masm
819 .mov(writable!(tmp_index), offset.reg.into(), OperandSize::S64)?;
820 self.masm
821 .mov(writable!(tmp_init), init.reg.into(), OperandSize::S64)?;
822
823 // Spill all this loop's variables onto the stack.
824 self.context.stack.push(TypedReg::i64(len.reg).into());
825 self.context.stack.push(TypedReg::i64(init.reg).into());
826 self.context.stack.push(TypedReg::i64(offset.reg).into());
827
828 // Emit `table.set`, consuming our temporary registers.
829 self.context.stack.push(TypedReg::i64(tmp_index).into());
830 self.context.stack.push(TypedReg::i64(tmp_init).into());

Callers 2

visit_table_fillMethod · 0.80
emit_table_growMethod · 0.80

Calls 15

i64Function · 0.85
OkFunction · 0.85
pop_to_regMethod · 0.80
resolve_table_dataMethod · 0.80
any_gprMethod · 0.80
free_regMethod · 0.80
try_intoMethod · 0.45
index_typeMethod · 0.45
movMethod · 0.45
checked_uaddMethod · 0.45
cmpMethod · 0.45

Tested by

no test coverage detected