let __fut = {{ call_expr }};
// ~keep 32 MiB: the runtime below is a *current-thread* runtime, so it spawns no
// workers and `thread_stack_size` would govern nothing that matters here —
// `block_on` drives the host callback future on this very thread. A thread from
// the bare `std::thread::spawn` this replaces gets Rust's 2 MiB default, which a
// deep callback future overflows, and a stack overflow aborts the process with
// SIGBUS instead of raising a catchable panic. Matches the Rustler bridge, which
// widens its own calling thread to the same 32 MiB for the same reason.
const VISITOR_BLOCK_ON_STACK_SIZE_BYTES: usize = 32 * 1024 * 1024;
{% if has_error %}
let {{ result_var }} = std::thread::Builder::new()
.stack_size(VISITOR_BLOCK_ON_STACK_SIZE_BYTES)
.spawn(move || {
::tokio::runtime::Builder::new_current_thread()
.build()
.expect("build alef visitor tokio runtime")
.block_on(__fut)
})
.expect("spawn alef visitor block_on thread")
.join()
.expect("thread panicked");
{% else %}
let {{ result_var }} = match std::thread::Builder::new()
.stack_size(VISITOR_BLOCK_ON_STACK_SIZE_BYTES)
.spawn(move || {
::tokio::runtime::Builder::new_current_thread()
.build()
.expect("build alef visitor tokio runtime")
.block_on(__fut)
})
.expect("spawn alef visitor block_on thread")
.join()
{
Ok(v) => v,
Err(e) => {
let msg = e
.downcast_ref::<&str>()
.map(|s| (*s).to_string())
.or_else(|| e.downcast_ref::<String>().cloned())
.unwrap_or_else(|| "non-string panic payload".to_string());
{% if resume_panic %}
// Excluded core return types carry no Default guarantee, so a
// substituted value is not an option here — log the failure,
// then re-raise the original panic (previous behavior, now
// observable).
tracing::warn!(wrapper = "{{ wrapper }}", method = "{{ method_name }}", error = %msg, "host callback panicked");
std::panic::resume_unwind(e);
{% else %}
// This method's Rust signature is infallible, so a panic on the
// callback thread cannot propagate. Log before substituting the
// default — a silent default is indistinguishable from a real
// result to the caller.
tracing::warn!(wrapper = "{{ wrapper }}", method = "{{ method_name }}", error = %msg, "host callback panicked; returning default");
return Default::default();
{% endif %}
}
};
{% endif %}