@@ -45,6 +45,8 @@ call_upcall_on_c_stack(rust_task *task, void *args, void *fn_ptr) {
45
45
task->call_on_c_stack (args, fn_ptr);
46
46
}
47
47
48
+ typedef void (*CDECL stack_switch_shim)(void *);
49
+
48
50
/* *********************************************************************
49
51
* Switches to the C-stack and invokes |fn_ptr|, passing |args| as argument.
50
52
* This is used by the C compiler to call foreign functions and by other
@@ -54,13 +56,20 @@ call_upcall_on_c_stack(rust_task *task, void *args, void *fn_ptr) {
54
56
*/
55
57
extern " C" CDECL void
56
58
upcall_call_shim_on_c_stack (void *args, void *fn_ptr) {
57
- rust_task *task = rust_get_current_task ();
58
-
59
- try {
60
- task->call_on_c_stack (args, fn_ptr);
61
- } catch (...) {
62
- // Logging here is not reliable
63
- assert (false && " Foreign code threw an exception" );
59
+ rust_task *task = rust_try_get_current_task ();
60
+
61
+ if (task) {
62
+ // We're running in task context, do a stack switch
63
+ try {
64
+ task->call_on_c_stack (args, fn_ptr);
65
+ } catch (...) {
66
+ // Logging here is not reliable
67
+ assert (false && " Foreign code threw an exception" );
68
+ }
69
+ } else {
70
+ // There's no task. Call the function and hope for the best
71
+ stack_switch_shim f = (stack_switch_shim)fn_ptr;
72
+ f (args);
64
73
}
65
74
}
66
75
@@ -70,15 +79,22 @@ upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
70
79
*/
71
80
extern " C" CDECL void
72
81
upcall_call_shim_on_rust_stack (void *args, void *fn_ptr) {
73
- rust_task *task = rust_get_current_task ();
74
-
75
- try {
76
- task->call_on_rust_stack (args, fn_ptr);
77
- } catch (...) {
78
- // We can't count on being able to unwind through arbitrary
79
- // code. Our best option is to just fail hard.
80
- // Logging here is not reliable
81
- assert (false && " Rust task failed after reentering the Rust stack" );
82
+ rust_task *task = rust_try_get_current_task ();
83
+
84
+ if (task) {
85
+ try {
86
+ task->call_on_rust_stack (args, fn_ptr);
87
+ } catch (...) {
88
+ // We can't count on being able to unwind through arbitrary
89
+ // code. Our best option is to just fail hard.
90
+ // Logging here is not reliable
91
+ assert (false
92
+ && " Rust task failed after reentering the Rust stack" );
93
+ }
94
+ } else {
95
+ // There's no task. Call the function and hope for the best
96
+ stack_switch_shim f = (stack_switch_shim)fn_ptr;
97
+ f (args);
82
98
}
83
99
}
84
100
0 commit comments