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

Method from

winch/codegen/src/abi/mod.rs:310–365  ·  view source on GitHub ↗

Creates [`ABIResults`] from a slice of `WasmType`. This function maps the given return types to their ABI specific representation. It does so, by iterating over them and applying the given `map` closure. The map closure takes a [WasmValType], maps its ABI representation, according to the calling convention. In the case of results, one result is stored in registers and the rest at particular offset

(
        returns: &[WasmValType],
        call_conv: &CallingConvention,
        mut map: F,
    )

Source from the content-addressed store, hash-verified

308 /// results, one result is stored in registers and the rest at particular
309 /// offsets in the stack.
310 pub fn from<F>(
311 returns: &[WasmValType],
312 call_conv: &CallingConvention,
313 mut map: F,
314 ) -> Result<Self>
315 where
316 F: FnMut(&WasmValType, u32) -> Result<(ABIOperand, u32)>,
317 {
318 if returns.len() == 0 {
319 return Ok(Self::default());
320 }
321
322 type FoldTuple = (SmallVec<[ABIOperand; 6]>, HashSet<Reg>, u32);
323 type FoldTupleResult = Result<FoldTuple>;
324
325 let fold_impl =
326 |(mut operands, mut regs, stack_bytes): FoldTuple, arg| -> FoldTupleResult {
327 let (operand, bytes) = map(arg, stack_bytes)?;
328 if operand.is_reg() {
329 regs.insert(operand.unwrap_reg());
330 }
331 operands.push(operand);
332 Ok((operands, regs, bytes))
333 };
334
335 // When dealing with multiple results, Winch's calling convention stores the
336 // last return value in a register rather than the first one. In that
337 // sense, Winch's return values in the ABI signature are "reversed" in
338 // terms of storage. This technique is particularly helpful to ensure that
339 // the following invariants are maintained:
340 // * Spilled memory values always precede register values
341 // * Spilled values are stored from oldest to newest, matching their
342 // respective locations on the machine stack.
343 let (mut operands, regs, bytes) = if call_conv.is_default() {
344 returns
345 .iter()
346 .rev()
347 .try_fold((SmallVec::new(), HashSet::with_capacity(1), 0), fold_impl)?
348 } else {
349 returns
350 .iter()
351 .try_fold((SmallVec::new(), HashSet::with_capacity(1), 0), fold_impl)?
352 };
353
354 // Similar to above, we reverse the result of the operands calculation
355 // to ensure that they match the declared order.
356 if call_conv.is_default() {
357 operands.reverse();
358 }
359
360 Ok(Self::new(ABIOperands {
361 inner: operands,
362 regs,
363 bytes,
364 }))
365 }
366
367 /// Create a new [`ABIResults`] from [`ABIOperands`].

Callers

nothing calls this directly

Calls 12

OkFunction · 0.85
ptr_type_from_ptr_sizeFunction · 0.85
reverseMethod · 0.80
newFunction · 0.50
lenMethod · 0.45
is_regMethod · 0.45
insertMethod · 0.45
unwrap_regMethod · 0.45
pushMethod · 0.45
is_defaultMethod · 0.45
iterMethod · 0.45
minMethod · 0.45

Tested by

no test coverage detected