This function is based on the GuestTask::caller field, which is prone to use-after-free errors. Specifically, if a task creates a subtask and then exits before the subtask exits, the caller field will be a table index which is no longer valid, leading to an error at best or silently incorrect behavior at worst (e.g. if that index is reused for a different purpose) if it is used again.
Earlier versions of Wasmtime ensured that GuestTask::caller remained correct regardless of the order in which caller and callee exited. It did so by reparenting subtasks when their callers exited. However, that was based on an earlier version of the component model specification which is no longer relevant, so that code was removed.
One of the main motivations for adding StoreContextMut::async_call_stack was to support attributing a guest->host import call to a corresponding host->guest export call. However, that doesn't need the full call stack, just some sort of scalar identifier to uniquely represent the export call. One way to address that would be to provide an API for passing an embedder-supplied identifier when calling the guest and passing it along to any transitive subtasks created by that call. That identifier could be e.g. a UUID or an Arc<T>, where T is a custom type that contains embedder-specific context for the call.
If the above approach suffices for attribution, we could remove async_call_stack. Alternatively, if we feel async_call_stack still has value for e.g. debugging and error reporting, we could restore the earlier Wasmtime behavior where each task keeps track of its subtasks and reparents them when it exits (with clear internal documentation that those fields are for debugging and error reporting only and not to be used in a "load bearing" way).
This function is based on the
GuestTask::callerfield, which is prone to use-after-free errors. Specifically, if a task creates a subtask and then exits before the subtask exits, thecallerfield will be a table index which is no longer valid, leading to an error at best or silently incorrect behavior at worst (e.g. if that index is reused for a different purpose) if it is used again.Earlier versions of Wasmtime ensured that
GuestTask::callerremained correct regardless of the order in which caller and callee exited. It did so by reparenting subtasks when their callers exited. However, that was based on an earlier version of the component model specification which is no longer relevant, so that code was removed.One of the main motivations for adding
StoreContextMut::async_call_stackwas to support attributing a guest->host import call to a corresponding host->guest export call. However, that doesn't need the full call stack, just some sort of scalar identifier to uniquely represent the export call. One way to address that would be to provide an API for passing an embedder-supplied identifier when calling the guest and passing it along to any transitive subtasks created by that call. That identifier could be e.g. a UUID or anArc<T>, whereTis a custom type that contains embedder-specific context for the call.If the above approach suffices for attribution, we could remove
async_call_stack. Alternatively, if we feelasync_call_stackstill has value for e.g. debugging and error reporting, we could restore the earlier Wasmtime behavior where each task keeps track of its subtasks and reparents them when it exits (with clear internal documentation that those fields are for debugging and error reporting only and not to be used in a "load bearing" way).