about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2011-11-18 15:40:23 -0800
committerNiko Matsakis <niko@alum.mit.edu>2011-11-18 16:32:19 -0800
commit9fa44a41e67151c5c392e2bd2b3989d74703efec (patch)
treeca51d17b4108c5ea64d997f04d423cbe90fc956b /src/rt
parent6072ddad33e034a63bddd1ef577492b2842e8136 (diff)
downloadrust-9fa44a41e67151c5c392e2bd2b3989d74703efec.tar.gz
rust-9fa44a41e67151c5c392e2bd2b3989d74703efec.zip
get pure wrappers approach running
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/arch/i386/ccall.S17
-rw-r--r--src/rt/arch/i386/context.h6
-rw-r--r--src/rt/arch/x86_64/ccall.S16
-rw-r--r--src/rt/arch/x86_64/context.h6
-rw-r--r--src/rt/rust_upcall.cpp10
-rw-r--r--src/rt/rustrt.def.in2
6 files changed, 57 insertions, 0 deletions
diff --git a/src/rt/arch/i386/ccall.S b/src/rt/arch/i386/ccall.S
index 297f4c79569..370c0e7c990 100644
--- a/src/rt/arch/i386/ccall.S
+++ b/src/rt/arch/i386/ccall.S
@@ -45,3 +45,20 @@ upcall_call_c_stack_shim:
     movl %ebp,%esp          // would like to use "leave" but it's slower
     popl %ebp
     ret
+
+#if defined(__APPLE__) || defined(_WIN32)
+.globl _asm_call_on_stack
+_asm_call_on_stack:
+#else
+.globl asm_call_on_stack
+asm_call_on_stack:
+#endif
+    pushl %ebp
+    movl %esp,%ebp          // save esp
+    movl 16(%ebp),%esp      // load new esp
+    subl $12,%esp           // maintain 16-byte alignment
+    pushl 8(%ebp)           // push ptr to argument block
+    calll *12(%ebp)
+    movl %ebp,%esp          // would like to use "leave" but it's slower
+    popl %ebp
+    ret
diff --git a/src/rt/arch/i386/context.h b/src/rt/arch/i386/context.h
index e36db0d0121..fc5eb900a5c 100644
--- a/src/rt/arch/i386/context.h
+++ b/src/rt/arch/i386/context.h
@@ -29,6 +29,8 @@ struct registers_t {
   uint32_t eip;
 };
 
+extern "C" void asm_call_on_stack(void *args, void *fn_ptr, uintptr_t stack_ptr);
+
 class context {
 public:
   registers_t regs;
@@ -55,6 +57,10 @@ public:
 
     return reinterpret_cast<void *>(top);
   }
+
+  void call_shim_on_c_stack(void *args, void *fn_ptr) {
+      asm_call_on_stack(args, fn_ptr, regs.esp);
+  }
 };
 
 #endif
diff --git a/src/rt/arch/x86_64/ccall.S b/src/rt/arch/x86_64/ccall.S
index 7ea29f2cea1..943a2027907 100644
--- a/src/rt/arch/x86_64/ccall.S
+++ b/src/rt/arch/x86_64/ccall.S
@@ -2,6 +2,7 @@
 
 #define ARG0 RUSTRT_ARG0_S
 #define ARG1 RUSTRT_ARG1_S
+#define ARG2 RUSTRT_ARG2_S
         
         .text
 
@@ -72,3 +73,18 @@ upcall_call_c_stack_shim:
     mov %rbp,%rsp
     pop %rbp
     ret
+
+#if defined(__APPLE__) || defined(_WIN32)
+.globl _asm_call_on_stack
+_asm_call_on_stack:
+#else
+.globl asm_call_on_stack
+asm_call_on_stack:
+#endif
+    push %rbp
+    mov %rsp,%rbp          // save rsp
+    mov ARG2,%rsp          // switch stack
+    call *ARG1             // invoke target address
+    mov %rbp,%rsp
+    pop %rbp
+    ret
diff --git a/src/rt/arch/x86_64/context.h b/src/rt/arch/x86_64/context.h
index 75427d473f9..11c85092747 100644
--- a/src/rt/arch/x86_64/context.h
+++ b/src/rt/arch/x86_64/context.h
@@ -29,6 +29,8 @@ struct registers_t {
     uint64_t data[RUSTRT_MAX];
 };
 
+extern "C" void asm_call_on_stack(void *args, void *fn_ptr, uintptr_t stack_ptr);
+
 class context {
 public:
     registers_t regs;
@@ -55,6 +57,10 @@ public:
 
         return reinterpret_cast<void *>(top);
     }
+
+    void call_shim_on_c_stack(void *args, void *fn_ptr) {
+        asm_call_on_stack(args, fn_ptr, regs.data[RUSTRT_RSP]);
+    }
 };
 
 #endif
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index c0544383d23..aac4212cac7 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -219,6 +219,16 @@ upcall_alloc_c_stack(size_t nbytes) {
     return sched->c_context.alloc_stack(nbytes);
 }
 
+/**
+ * Allocates |nbytes| bytes in the C stack and returns a pointer to the start
+ * of the allocated space.
+ */
+extern "C" CDECL void
+upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
+    rust_scheduler *sched = rust_scheduler::get_task()->sched;
+    sched->c_context.call_shim_on_c_stack(args, fn_ptr);
+}
+
 extern "C" _Unwind_Reason_Code
 __gxx_personality_v0(int version,
                      _Unwind_Action actions,
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 3147eeeca40..c0a9a92ba1b 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -74,3 +74,5 @@ upcall_shared_malloc
 upcall_shared_free
 upcall_vec_grow
 upcall_vec_push
+upcall_call_shim_on_c_stack
+asm_call_on_stack
\ No newline at end of file