Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 9 additions & 37 deletions crates/core/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,7 @@ impl<'a, B: Bindgen> Generator<'a, B> {
let mut offset = 0;
for (_, ty) in func.params.iter() {
let types = flat_types(self.resolve, ty, Some(max_flat_params))
.expect("direct parameter load failed to produce types during generation of fn call");
.expect(&format!("direct parameter load failed to produce types during generation of fn call (func name: '{}')", func.name));
for _ in 0..types.len() {
self.emit(&Instruction::GetArg { nth: offset });
offset += 1;
Expand All @@ -1134,37 +1134,21 @@ impl<'a, B: Bindgen> Generator<'a, B> {
// interface function completes, so lowering is conditional
// based on slightly different logic for the `task.return`
// intrinsic.
let (lower_to_memory, async_flat_results) = match (variant, async_, &func.result) {
// Async guest imports return a i32 status code
(
AbiVariant::GuestImport | AbiVariant::GuestImportAsync,
_is_async @ true,
None,
) => {
unreachable!("async guest imports always return a result")
}
// Async guest imports return a i32 status code
(
AbiVariant::GuestImport | AbiVariant::GuestImportAsync,
_is_async @ true,
Some(ty),
) => {
// For async guest imports, we know whether we must lower results
// if there are no params (i.e. the usual out pointer wasn't even required)
// and we always know the return value will be a i32 status code
assert!(matches!(ty, Type::U32 | Type::S32));
(sig.params.is_empty(), Some(Some(vec![WasmType::I32])))
}
// All other async cases
(_, _is_async @ true, func_result) => {
//
// Note that in the async import case teh code below deals with the CM function being lowered,
// not the core function that is underneath that (i.e. func.result may be empty,
// where the associated core function underneath must have a i32 status code result)
let (lower_to_memory, async_flat_results) = match (async_, &func.result) {
// All async cases pass along the function results and flatten where necesary
(_is_async @ true, func_result) => {
let results = match &func_result {
Some(ty) => flat_types(self.resolve, ty, Some(max_flat_params)),
None => Some(Vec::new()),
};
(results.is_none(), Some(results))
}
// All other non-async cases
(_, _is_async @ false, _) => (sig.retptr, None),
(_is_async @ false, _) => (sig.retptr, None),
};

// This was dynamically allocated by the caller (or async start
Expand All @@ -1188,18 +1172,6 @@ impl<'a, B: Bindgen> Generator<'a, B> {

// Perform memory lowing of relevant results, including out pointers as well as traditional results
match (lower_to_memory, sig.retptr, variant) {
// Async guest imports with do no lowering cannot have ret pointers
// not having to do lowering implies that there was no return pointer provided
(_lower_to_memory @ false, _has_ret_ptr @ true, AbiVariant::GuestImport)
if async_ =>
{
unreachable!(
"async guest import cannot avoid lowering when a ret ptr is present ({async_note} func [{func_name}], variant {variant:#?})",
async_note = async_.then_some("async").unwrap_or("sync"),
func_name = func.name,
)
}

// For sync calls, if no lowering to memory is required and there *is* a return pointer in use
// then we need to lower then simply lower the result(s) and return that directly from the function.
(_lower_to_memory @ false, _, _) => {
Expand Down
Loading