// This runs on the Rust stack void task_start_wrapper(spawn_args *a) { rust_task *task = a->task; bool threw_exception = false; try { // The first argument is the return pointer; as the task fn // must have void return type, we can safely pass 0. a->f(0, a->envptr, a->argptr); } catch (rust_task *ex) { assert(ex == task && "Expected this task to be thrown for unwinding"); threw_exception = true; if (task->c_stack) { task->return_c_stack(); } // Since we call glue code below we need to make sure we // have the stack limit set up correctly task->reset_stack_limit(); } // We should have returned any C stack by now assert(task->c_stack == NULL); rust_opaque_box* env = a->envptr; if(env) { // free the environment (which should be a unique closure). const type_desc *td = env->td; td->drop_glue(NULL, NULL, NULL, box_body(env)); upcall_exchange_free(env); } // The cleanup work needs lots of stack cleanup_args ca = {a, threw_exception}; task->call_on_c_stack(&ca, (void*)cleanup_task); task->ctx.next->swap(task->ctx); }
// FIXME (#2861): Alias used by libcore/rt.rs to avoid naming conflicts with // autogenerated wrappers for upcall_exchange_free. Remove this when we fully // move away away from the C upcall path. extern "C" CDECL void rust_upcall_exchange_free(void *ptr) { return upcall_exchange_free(ptr); }