about summary refs log tree commit diff
path: root/src/rt/rust_upcall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rt/rust_upcall.cpp')
-rw-r--r--src/rt/rust_upcall.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index d12e7311303..8751a4b13e5 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -71,13 +71,38 @@ upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
     try {
         task->call_on_c_stack(args, fn_ptr);
     } catch (...) {
-        A(task->thread, false, "Native code threw an exception");
+        LOG_ERR(task, task, "Native code threw an exception");
+        abort();
     }
 
     task = rust_task_thread::get_task();
     task->record_stack_limit();
 }
 
+/*
+ * The opposite of above. Starts on a C stack and switches to the Rust
+ * stack. This is the only upcall that runs from the C stack.
+ */
+extern "C" CDECL void
+upcall_call_shim_on_rust_stack(void *args, void *fn_ptr) {
+    rust_task *task = rust_task_thread::get_task();
+
+    // FIXME: Because of the hack in the other function that disables the
+    // stack limit when entering the C stack, here we restore the stack limit
+    // again.
+    task->record_stack_limit();
+
+    try {
+        task->call_on_rust_stack(args, fn_ptr);
+    } catch (...) {
+        // We can't count on being able to unwind through arbitrary
+        // code. Our best option is to just fail hard.
+        LOG_ERR(task, task,
+                "Rust task failed after reentering the Rust stack");
+        abort();
+    }
+}
+
 /**********************************************************************/
 
 struct s_fail_args {