]> git.lizzy.rs Git - rust.git/commitdiff
rt: Create different stack-switching paths for upcalls and shims
authorBrian Anderson <banderson@mozilla.com>
Mon, 19 Dec 2011 00:17:52 +0000 (16:17 -0800)
committerBrian Anderson <banderson@mozilla.com>
Mon, 19 Dec 2011 00:17:55 +0000 (16:17 -0800)
Shims need to play with the stack limit, upcalls don't. Only one upcall,
upcall_fail is allowed to catch, and we need a find a way to get rid of that
catch as well because it results in _Unwind_Resume running off the end of the
Rust stack.

src/rt/rust_upcall.cpp

index 7b5dbd38bdd558f89ece04e7ac11ff353ae3c076..506441979cacfef545e77a78e8af50d8868ddd12 100644 (file)
@@ -27,7 +27,15 @@ check_stack_alignment() __attribute__ ((aligned (16)));
 static void check_stack_alignment() { }
 #endif
 
-#define SWITCH_STACK(A, F) upcall_call_shim_on_c_stack((void*)A, (void*)F)
+#define UPCALL_SWITCH_STACK(A, F) call_upcall_on_c_stack((void*)A, (void*)F)
+
+inline void
+call_upcall_on_c_stack(void *args, void *fn_ptr) {
+    check_stack_alignment();
+    rust_task *task = rust_scheduler::get_task();
+    rust_scheduler *sched = task->sched;
+    sched->c_context.call_shim_on_c_stack(args, fn_ptr);
+}
 
 extern "C" void record_sp(void *limit);
 
@@ -35,7 +43,8 @@ extern "C" void record_sp(void *limit);
  * Switches to the C-stack and invokes |fn_ptr|, passing |args| as argument.
  * This is used by the C compiler to call native functions and by other
  * upcalls to switch to the C stack.  The return value is passed through a
- * field in the args parameter.
+ * field in the args parameter. This upcall is specifically for switching
+ * to the shim functions generated by rustc.
  */
 extern "C" CDECL void
 upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
@@ -51,10 +60,9 @@ upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
     try {
         sched->c_context.call_shim_on_c_stack(args, fn_ptr);
     } catch (...) {
-        task = rust_scheduler::get_task();
-        task->record_stack_limit();
-        throw;
+        A(sched, false, "Native code threw an exception");
     }
+
     task = rust_scheduler::get_task();
     task->record_stack_limit();
 }
@@ -80,8 +88,12 @@ extern "C" CDECL void
 upcall_fail(char const *expr,
             char const *file,
             size_t line) {
-    s_fail_args args = {expr,file,line};
-    SWITCH_STACK(&args, upcall_s_fail);
+    try {
+        s_fail_args args = {expr,file,line};
+        UPCALL_SWITCH_STACK(&args, upcall_s_fail);
+    } catch (rust_task*) {
+        throw;
+    }
 }
 
 /**********************************************************************
@@ -124,7 +136,7 @@ upcall_s_malloc(s_malloc_args *args) {
 extern "C" CDECL uintptr_t
 upcall_malloc(size_t nbytes, type_desc *td) {
     s_malloc_args args = {0, nbytes, td};
-    SWITCH_STACK(&args, upcall_s_malloc);
+    UPCALL_SWITCH_STACK(&args, upcall_s_malloc);
     return args.retval;
 }
 
@@ -156,7 +168,7 @@ upcall_s_free(s_free_args *args) {
 extern "C" CDECL void
 upcall_free(void* ptr, uintptr_t is_gc) {
     s_free_args args = {ptr, is_gc};
-    SWITCH_STACK(&args, upcall_s_free);
+    UPCALL_SWITCH_STACK(&args, upcall_s_free);
 }
 
 /**********************************************************************
@@ -189,7 +201,7 @@ upcall_s_shared_malloc(s_shared_malloc_args *args) {
 extern "C" CDECL uintptr_t
 upcall_shared_malloc(size_t nbytes, type_desc *td) {
     s_shared_malloc_args args = {0, nbytes, td};
-    SWITCH_STACK(&args, upcall_s_shared_malloc);
+    UPCALL_SWITCH_STACK(&args, upcall_s_shared_malloc);
     return args.retval;
 }
 
@@ -216,7 +228,7 @@ upcall_s_shared_free(s_shared_free_args *args) {
 extern "C" CDECL void
 upcall_shared_free(void* ptr) {
     s_shared_free_args args = {ptr};
-    SWITCH_STACK(&args, upcall_s_shared_free);
+    UPCALL_SWITCH_STACK(&args, upcall_s_shared_free);
 }
 
 /**********************************************************************
@@ -262,7 +274,7 @@ void upcall_s_create_shared_type_desc(s_create_shared_type_desc_args *args)
 extern "C" CDECL type_desc *
 upcall_create_shared_type_desc(type_desc *td) {
     s_create_shared_type_desc_args args = { td, 0 };
-    SWITCH_STACK(&args, upcall_s_create_shared_type_desc);
+    UPCALL_SWITCH_STACK(&args, upcall_s_create_shared_type_desc);
     return args.res;
 }
 
@@ -285,7 +297,7 @@ void upcall_s_free_shared_type_desc(type_desc *td)
 
 extern "C" CDECL void
 upcall_free_shared_type_desc(type_desc *td) {
-    SWITCH_STACK(td, upcall_s_free_shared_type_desc);
+    UPCALL_SWITCH_STACK(td, upcall_s_free_shared_type_desc);
 }
 
 /**********************************************************************
@@ -325,7 +337,7 @@ upcall_get_type_desc(void *curr_crate, // ignored, legacy compat.
                      type_desc const **descs,
                      uintptr_t n_obj_params) {
     s_get_type_desc_args args = {0,size,align,n_descs,descs,n_obj_params};
-    SWITCH_STACK(&args, upcall_s_get_type_desc);
+    UPCALL_SWITCH_STACK(&args, upcall_s_get_type_desc);
     return args.retval;
 }
 
@@ -347,7 +359,7 @@ upcall_s_vec_grow(s_vec_grow_args *args) {
 extern "C" CDECL void
 upcall_vec_grow(rust_vec** vp, size_t new_sz) {
     s_vec_grow_args args = {vp, new_sz};
-    SWITCH_STACK(&args, upcall_s_vec_grow);
+    UPCALL_SWITCH_STACK(&args, upcall_s_vec_grow);
 }
 
 // Copy elements from one vector to another,
@@ -414,7 +426,7 @@ upcall_s_dynastack_mark(s_dynastack_mark_args *args) {
 extern "C" CDECL void *
 upcall_dynastack_mark() {
     s_dynastack_mark_args args = {0};
-    SWITCH_STACK(&args, upcall_s_dynastack_mark);
+    UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_mark);
     return args.retval;
 }
 
@@ -439,7 +451,7 @@ upcall_s_dynastack_alloc(s_dynastack_alloc_args *args) {
 extern "C" CDECL void *
 upcall_dynastack_alloc(size_t sz) {
     s_dynastack_alloc_args args = {0, sz};
-    SWITCH_STACK(&args, upcall_s_dynastack_alloc);
+    UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_alloc);
     return args.retval;
 }
 
@@ -465,7 +477,7 @@ upcall_s_dynastack_alloc_2(s_dynastack_alloc_2_args *args) {
 extern "C" CDECL void *
 upcall_dynastack_alloc_2(size_t sz, type_desc *ty) {
     s_dynastack_alloc_2_args args = {0, sz, ty};
-    SWITCH_STACK(&args, upcall_s_dynastack_alloc_2);
+    UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_alloc_2);
     return args.retval;
 }
 
@@ -482,7 +494,7 @@ upcall_s_dynastack_free(s_dynastack_free_args *args) {
 extern "C" CDECL void
 upcall_dynastack_free(void *ptr) {
     s_dynastack_free_args args = {ptr};
-    SWITCH_STACK(&args, upcall_s_dynastack_free);
+    UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_free);
 }
 
 extern "C" _Unwind_Reason_Code
@@ -524,7 +536,7 @@ upcall_rust_personality(int version,
     s_rust_personality_args args = {(_Unwind_Reason_Code)0,
                                     version, actions, exception_class,
                                     ue_header, context};
-    SWITCH_STACK(&args, upcall_s_rust_personality);
+    UPCALL_SWITCH_STACK(&args, upcall_s_rust_personality);
     return args.retval;
 }
 
@@ -553,7 +565,7 @@ upcall_cmp_type(int8_t *result, const type_desc *tydesc,
                 const type_desc **subtydescs, uint8_t *data_0,
                 uint8_t *data_1, uint8_t cmp_type) {
     s_cmp_type_args args = {result, tydesc, subtydescs, data_0, data_1, cmp_type};
-    SWITCH_STACK(&args, upcall_s_cmp_type);
+    UPCALL_SWITCH_STACK(&args, upcall_s_cmp_type);
 }
 
 extern "C" void
@@ -573,7 +585,7 @@ upcall_s_log_type(s_log_type_args *args) {
 extern "C" void
 upcall_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level) {
     s_log_type_args args = {tydesc, data, level};
-    SWITCH_STACK(&args, upcall_s_log_type);
+    UPCALL_SWITCH_STACK(&args, upcall_s_log_type);
 }
 
 struct rust_new_stack2_args {