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

Method call_impl

crates/wasmtime/src/runtime/component/func/typed.rs:206–267  ·  view source on GitHub ↗
(&self, mut store: impl AsContextMut, params: Params)

Source from the content-addressed store, hash-verified

204 }
205
206 fn call_impl(&self, mut store: impl AsContextMut, params: Params) -> Result<Return> {
207 let mut store = store.as_context_mut();
208
209 if self.func.abi_async(store.0) {
210 bail!("must enable the `component-model-async` feature to call async-lifted exports")
211 }
212
213 // Note that this is in theory simpler than it might read at this time.
214 // Here we're doing a runtime dispatch on the `flatten_count` for the
215 // params/results to see whether they're inbounds. This creates 4 cases
216 // to handle. In reality this is a highly optimizable branch where LLVM
217 // will easily figure out that only one branch here is taken.
218 //
219 // Otherwise this current construction is done to ensure that the stack
220 // space reserved for the params/results is always of the appropriate
221 // size (as the params/results needed differ depending on the "flatten"
222 // count)
223 //
224 // SAFETY: the safety of these invocations of `call_raw` depends on the
225 // correctness of the ascription of the `LowerParams` and `LowerReturn`
226 // types on the `call_raw` function. That's upheld here through the
227 // safety requirements of `Lift` and `Lower` on `Params` and `Return` in
228 // combination with checking the various possible branches here and
229 // dispatching to appropriately typed functions.
230 let (result, post_return_arg) = unsafe {
231 // This type is used as `LowerParams` for `call_raw` which is either
232 // `Params::Lower` or `ValRaw` representing it's either on the stack
233 // or it's on the heap. This allocates 1 extra `ValRaw` on the stack
234 // if `Params` is empty and `Return` is also empty, but that's a
235 // reasonable enough price to pay for now given the current code
236 // organization.
237 #[derive(Copy, Clone)]
238 union Union<T: Copy, U: Copy> {
239 _a: T,
240 _b: U,
241 }
242
243 if Return::flatten_count() <= MAX_FLAT_RESULTS {
244 self.func.call_raw(
245 store.as_context_mut(),
246 |cx, ty, dst: &mut MaybeUninit<Union<Params::Lower, ValRaw>>| {
247 let dst = storage_as_slice_mut(dst);
248 Self::lower_args(cx, ty, dst, &params)
249 },
250 Self::lift_stack_result,
251 )
252 } else {
253 self.func.call_raw(
254 store.as_context_mut(),
255 |cx, ty, dst: &mut MaybeUninit<Union<Params::Lower, ValRaw>>| {
256 let dst = storage_as_slice_mut(dst);
257 Self::lower_args(cx, ty, dst, &params)
258 },
259 Self::lift_heap_result,
260 )
261 }
262 }?;
263

Callers 2

callMethod · 0.45
call_asyncMethod · 0.45

Calls 6

storage_as_slice_mutFunction · 0.85
OkFunction · 0.85
abi_asyncMethod · 0.80
post_return_implMethod · 0.80
as_context_mutMethod · 0.45
call_rawMethod · 0.45

Tested by

no test coverage detected