(&mut self, func: &Function, variant: AbiVariant, lift_lower: LiftLower, async_: bool)
| 1020 | } |
| 1021 | |
| 1022 | fn call(&mut self, func: &Function, variant: AbiVariant, lift_lower: LiftLower, async_: bool) { |
| 1023 | let sig = self.resolve.wasm_signature(variant, func); |
| 1024 | |
| 1025 | // Lowering parameters calling a wasm import _or_ returning a result |
| 1026 | // from an async-lifted wasm export means we don't need to pass |
| 1027 | // ownership, but we pass ownership in all other cases. |
| 1028 | let realloc = match (variant, lift_lower, async_) { |
| 1029 | (AbiVariant::GuestImport, LiftLower::LowerArgsLiftResults, _) |
| 1030 | | ( |
| 1031 | AbiVariant::GuestExport |
| 1032 | | AbiVariant::GuestExportAsync |
| 1033 | | AbiVariant::GuestExportAsyncStackful, |
| 1034 | LiftLower::LiftArgsLowerResults, |
| 1035 | true, |
| 1036 | ) => Realloc::None, |
| 1037 | _ => Realloc::Export("cabi_realloc"), |
| 1038 | }; |
| 1039 | assert!(self.realloc.is_none()); |
| 1040 | |
| 1041 | match lift_lower { |
| 1042 | LiftLower::LowerArgsLiftResults => { |
| 1043 | self.realloc = Some(realloc); |
| 1044 | |
| 1045 | // Create a function that performs individual lowering of operands |
| 1046 | let lower_to_memory = |self_: &mut Self, ptr: B::Operand| { |
| 1047 | let mut offset = ArchitectureSize::default(); |
| 1048 | for (nth, Param { ty, .. }) in func.params.iter().enumerate() { |
| 1049 | self_.emit(&Instruction::GetArg { nth }); |
| 1050 | offset = align_to_arch(offset, self_.bindgen.sizes().align(ty)); |
| 1051 | self_.write_to_memory(ty, ptr.clone(), offset); |
| 1052 | offset += self_.bindgen.sizes().size(ty); |
| 1053 | } |
| 1054 | |
| 1055 | self_.stack.push(ptr); |
| 1056 | }; |
| 1057 | |
| 1058 | // Lower parameters |
| 1059 | if sig.indirect_params { |
| 1060 | // If parameters are indirect space is |
| 1061 | // allocated for them and each argument is lowered |
| 1062 | // individually into memory. |
| 1063 | let ElementInfo { size, align } = self |
| 1064 | .bindgen |
| 1065 | .sizes() |
| 1066 | .record(func.params.iter().map(|param| ¶m.ty)); |
| 1067 | |
| 1068 | // Resolve the pointer to the indirectly stored parameters |
| 1069 | let ptr = match variant { |
| 1070 | // When a wasm module calls an import it will provide |
| 1071 | // space that isn't explicitly deallocated. |
| 1072 | AbiVariant::GuestImport => self.bindgen.return_pointer(size, align), |
| 1073 | |
| 1074 | AbiVariant::GuestImportAsync => { |
| 1075 | todo!("direct param lowering for async guest import not implemented") |
| 1076 | } |
| 1077 | |
| 1078 | // When calling a wasm module from the outside, though, |
| 1079 | // malloc needs to be called. |
no test coverage detected