Skip to content

Commit 92cca96

Browse files
fix(core): result check for async function (#1355)
* fix(core): result check for async function This commit fixes a check that was incorrectly looking at the CM level function in the case of an async guest import when determining whether it had the right results. The problem with the existing logic is that it was trying to check for a constraint on the wrong function -- the guest import being lowered rather than the core function underneath that. The case that makes this obvious was something like an `run: async func()` where the CM level function clearly has no result, but the underlying core function being async lifted must of course have a i32 status code as a result. * fix(core): remove check on guests avoiding lowering
1 parent eaf42f6 commit 92cca96

File tree

1 file changed

+9
-37
lines changed

1 file changed

+9
-37
lines changed

crates/core/src/abi.rs

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,7 @@ impl<'a, B: Bindgen> Generator<'a, B> {
11151115
let mut offset = 0;
11161116
for (_, ty) in func.params.iter() {
11171117
let types = flat_types(self.resolve, ty, Some(max_flat_params))
1118-
.expect("direct parameter load failed to produce types during generation of fn call");
1118+
.expect(&format!("direct parameter load failed to produce types during generation of fn call (func name: '{}')", func.name));
11191119
for _ in 0..types.len() {
11201120
self.emit(&Instruction::GetArg { nth: offset });
11211121
offset += 1;
@@ -1134,37 +1134,21 @@ impl<'a, B: Bindgen> Generator<'a, B> {
11341134
// interface function completes, so lowering is conditional
11351135
// based on slightly different logic for the `task.return`
11361136
// intrinsic.
1137-
let (lower_to_memory, async_flat_results) = match (variant, async_, &func.result) {
1138-
// Async guest imports return a i32 status code
1139-
(
1140-
AbiVariant::GuestImport | AbiVariant::GuestImportAsync,
1141-
_is_async @ true,
1142-
None,
1143-
) => {
1144-
unreachable!("async guest imports always return a result")
1145-
}
1146-
// Async guest imports return a i32 status code
1147-
(
1148-
AbiVariant::GuestImport | AbiVariant::GuestImportAsync,
1149-
_is_async @ true,
1150-
Some(ty),
1151-
) => {
1152-
// For async guest imports, we know whether we must lower results
1153-
// if there are no params (i.e. the usual out pointer wasn't even required)
1154-
// and we always know the return value will be a i32 status code
1155-
assert!(matches!(ty, Type::U32 | Type::S32));
1156-
(sig.params.is_empty(), Some(Some(vec![WasmType::I32])))
1157-
}
1158-
// All other async cases
1159-
(_, _is_async @ true, func_result) => {
1137+
//
1138+
// Note that in the async import case teh code below deals with the CM function being lowered,
1139+
// not the core function that is underneath that (i.e. func.result may be empty,
1140+
// where the associated core function underneath must have a i32 status code result)
1141+
let (lower_to_memory, async_flat_results) = match (async_, &func.result) {
1142+
// All async cases pass along the function results and flatten where necesary
1143+
(_is_async @ true, func_result) => {
11601144
let results = match &func_result {
11611145
Some(ty) => flat_types(self.resolve, ty, Some(max_flat_params)),
11621146
None => Some(Vec::new()),
11631147
};
11641148
(results.is_none(), Some(results))
11651149
}
11661150
// All other non-async cases
1167-
(_, _is_async @ false, _) => (sig.retptr, None),
1151+
(_is_async @ false, _) => (sig.retptr, None),
11681152
};
11691153

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

11891173
// Perform memory lowing of relevant results, including out pointers as well as traditional results
11901174
match (lower_to_memory, sig.retptr, variant) {
1191-
// Async guest imports with do no lowering cannot have ret pointers
1192-
// not having to do lowering implies that there was no return pointer provided
1193-
(_lower_to_memory @ false, _has_ret_ptr @ true, AbiVariant::GuestImport)
1194-
if async_ =>
1195-
{
1196-
unreachable!(
1197-
"async guest import cannot avoid lowering when a ret ptr is present ({async_note} func [{func_name}], variant {variant:#?})",
1198-
async_note = async_.then_some("async").unwrap_or("sync"),
1199-
func_name = func.name,
1200-
)
1201-
}
1202-
12031175
// For sync calls, if no lowering to memory is required and there *is* a return pointer in use
12041176
// then we need to lower then simply lower the result(s) and return that directly from the function.
12051177
(_lower_to_memory @ false, _, _) => {

0 commit comments

Comments
 (0)