Prepare (but do not start) a guest->guest call. This is called from fused adapter code generated in `wasmtime_environ::fact::trampoline::Compiler`. `start` and `return_` are synthesized Wasm functions which move the parameters from the caller to the callee and the result from the callee to the caller, respectively. The adapter will call `Self::start_call` immediately after calling this function
(
self,
mut store: StoreContextMut<T>,
start: NonNull<VMFuncRef>,
return_: NonNull<VMFuncRef>,
caller_instance: RuntimeComponentInstanceIndex,
callee_in
| 2588 | /// entities (and with the expected signatures for the function references |
| 2589 | /// -- see `wasmtime_environ::fact::trampoline::Compiler` for details). |
| 2590 | unsafe fn prepare_call<T: 'static>( |
| 2591 | self, |
| 2592 | mut store: StoreContextMut<T>, |
| 2593 | start: NonNull<VMFuncRef>, |
| 2594 | return_: NonNull<VMFuncRef>, |
| 2595 | caller_instance: RuntimeComponentInstanceIndex, |
| 2596 | callee_instance: RuntimeComponentInstanceIndex, |
| 2597 | task_return_type: TypeTupleIndex, |
| 2598 | callee_async: bool, |
| 2599 | memory: *mut VMMemoryDefinition, |
| 2600 | string_encoding: StringEncoding, |
| 2601 | caller_info: CallerInfo, |
| 2602 | ) -> Result<()> { |
| 2603 | if let (CallerInfo::Sync { .. }, true) = (&caller_info, callee_async) { |
| 2604 | // A task may only call an async-typed function via a sync lower if |
| 2605 | // it was created by a call to an async export. Otherwise, we'll |
| 2606 | // trap. |
| 2607 | store.0.check_blocking()?; |
| 2608 | } |
| 2609 | |
| 2610 | enum ResultInfo { |
| 2611 | Heap { results: u32 }, |
| 2612 | Stack { result_count: u32 }, |
| 2613 | } |
| 2614 | |
| 2615 | let result_info = match &caller_info { |
| 2616 | CallerInfo::Async { |
| 2617 | has_result: true, |
| 2618 | params, |
| 2619 | } => ResultInfo::Heap { |
| 2620 | results: match params.last() { |
| 2621 | Some(r) => r.get_u32(), |
| 2622 | None => bail_bug!("retptr missing"), |
| 2623 | }, |
| 2624 | }, |
| 2625 | CallerInfo::Async { |
| 2626 | has_result: false, .. |
| 2627 | } => ResultInfo::Stack { result_count: 0 }, |
| 2628 | CallerInfo::Sync { |
| 2629 | result_count, |
| 2630 | params, |
| 2631 | } if *result_count > u32::try_from(MAX_FLAT_RESULTS)? => ResultInfo::Heap { |
| 2632 | results: match params.last() { |
| 2633 | Some(r) => r.get_u32(), |
| 2634 | None => bail_bug!("arg ptr missing"), |
| 2635 | }, |
| 2636 | }, |
| 2637 | CallerInfo::Sync { result_count, .. } => ResultInfo::Stack { |
| 2638 | result_count: *result_count, |
| 2639 | }, |
| 2640 | }; |
| 2641 | |
| 2642 | let sync_caller = matches!(caller_info, CallerInfo::Sync { .. }); |
| 2643 | |
| 2644 | // Create a new guest task for the call, closing over the `start` and |
| 2645 | // `return_` functions to lift the parameters and lower the result, |
| 2646 | // respectively. |
| 2647 | let start = SendSyncPtr::new(start); |
no test coverage detected