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

Method emit_table_get

winch/codegen/src/codegen/mod.rs:571–658  ·  view source on GitHub ↗
(&mut self, table_index: TableIndex)

Source from the content-addressed store, hash-verified

569 }
570
571 pub fn emit_table_get(&mut self, table_index: TableIndex) -> Result<()> {
572 let table = self.env.table(table_index);
573 let heap_type = table.ref_type.heap_type;
574 ensure!(
575 heap_type == WasmHeapType::Func,
576 CodeGenError::unsupported_wasm_type()
577 );
578 ensure!(
579 self.tunables.table_lazy_init,
580 CodeGenError::unsupported_table_eager_init()
581 );
582 let table_data = self.env.resolve_table_data(table_index);
583 let ptr_type = self.env.ptr_type();
584 let builtin = self.env.builtins.table_get_lazy_init_func_ref::<M::ABI>()?;
585
586 // Request the builtin's result register and use it to hold the table
587 // element value. We preemptively spill and request this register to
588 // avoid conflict at the control flow merge below. Requesting the result
589 // register is safe since we know ahead-of-time the builtin's signature.
590 self.context.spill(self.masm)?;
591 let elem_value: Reg = self.context.reg(
592 builtin.sig().results.unwrap_singleton().unwrap_reg(),
593 self.masm,
594 )?;
595
596 let index = self.context.pop_to_reg(self.masm, None)?;
597 let base = self.context.any_gpr(self.masm)?;
598
599 let elem_addr = self.emit_compute_table_elem_addr(index.into(), base, &table_data)?;
600 self.masm.load_ptr(elem_addr, writable!(elem_value))?;
601 // Free the register used as base, once we have loaded the element
602 // address into the element value register.
603 self.context.free_reg(base);
604
605 let (defined, cont) = (self.masm.get_label()?, self.masm.get_label()?);
606
607 // Push the built-in arguments to the stack.
608 self.context
609 .stack
610 .extend([table_index.as_u32().try_into().unwrap(), index.into()]);
611
612 self.masm.branch(
613 IntCmpKind::Ne,
614 elem_value,
615 elem_value.into(),
616 defined,
617 ptr_type.try_into()?,
618 )?;
619 // Free the element value register.
620 // This is safe since the FnCall::emit call below, will ensure
621 // that the result register is placed on the value stack.
622 self.context.free_reg(elem_value);
623 FnCall::emit::<M>(
624 &mut self.env,
625 self.masm,
626 &mut self.context,
627 Callee::Builtin(builtin.clone()),
628 )?;

Callers 3

visit_call_indirectMethod · 0.80
visit_table_getMethod · 0.80
emit_table_copyMethod · 0.80

Calls 15

i64Function · 0.85
resolve_table_dataMethod · 0.80
spillMethod · 0.80
unwrap_singletonMethod · 0.80
pop_to_regMethod · 0.80
any_gprMethod · 0.80
free_regMethod · 0.80
tableMethod · 0.45
ptr_typeMethod · 0.45
regMethod · 0.45
unwrap_regMethod · 0.45

Tested by

no test coverage detected