about summary refs log tree commit diff
path: root/src/rt/arch
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-11-14 13:52:35 -0800
committerBrian Anderson <banderson@mozilla.com>2011-11-17 10:52:59 -0800
commite6c3c4e48c6187212b5bb21b5fdb521660b6b510 (patch)
treef558c547c4f68221dbd14392fc35c938ad6f762d /src/rt/arch
parentf4eb25e0d032495fef50c445b211f2c2ff20eb9c (diff)
downloadrust-e6c3c4e48c6187212b5bb21b5fdb521660b6b510.tar.gz
rust-e6c3c4e48c6187212b5bb21b5fdb521660b6b510.zip
rt: More work on morestack
Diffstat (limited to 'src/rt/arch')
-rw-r--r--src/rt/arch/i386/morestack.S119
1 files changed, 98 insertions, 21 deletions
diff --git a/src/rt/arch/i386/morestack.S b/src/rt/arch/i386/morestack.S
index 2f5987a4350..ec356ea91c6 100644
--- a/src/rt/arch/i386/morestack.S
+++ b/src/rt/arch/i386/morestack.S
@@ -2,40 +2,117 @@
 
 // __morestack
 //
-// LLVM generates a call to this to allocate more stack space in a functiono
+// LLVM generates a call to this to allocate more stack space in a function
 // prolog when we run out.
 
 #if defined(__APPLE__) || defined(_WIN32)
-#define RUST_NEW_STACK      _rust_new_stack
-#define RUST_DEL_STACK      _rust_del_stack
-#define MORESTACK           ___morestack
+#define RUST_NEW_STACK          _rust_new_stack
+#define RUST_DEL_STACK          _rust_del_stack
+#define RUST_GET_PREV_STACK     _rust_get_prev_stack
+#define RUST_GET_TASK           _rust_get_task
+#define UPCALL_ALLOC_C_STACK    _upcall_alloc_c_stack
+#define UPCALL_CALL_C_STACK     _upcall_call_c_stack
+#define MORESTACK               ___morestack
 #else
-#define RUST_NEW_STACK      rust_new_stack
-#define RUST_DEL_STACK      rust_del_stack
-#define MORESTACK           __morestack
+#define RUST_NEW_STACK          rust_new_stack
+#define RUST_DEL_STACK          rust_del_stack
+#define RUST_GET_PREV_STACK     rust_get_prev_stack
+#define RUST_GET_TASK           rust_get_task
+#define UPCALL_ALLOC_C_STACK    upcall_alloc_c_stack
+#define UPCALL_CALL_C_STACK     upcall_call_c_stack
+#define MORESTACK               __morestack
 #endif
 
+#ifdef __APPLE__
+#define ALIGNMENT               4
+#else
+#define ALIGNMENT               8
+#endif
+
+#define RETURN_OFFSET   7
+
 .globl RUST_NEW_STACK
 .globl RUST_DEL_STACK
-
+.globl RUST_GET_PREV_STACK
+.globl RUST_GET_TASK
+.globl UPCALL_ALLOC_C_STACK
+.globl UPCALL_CALL_C_STACK
 .globl MORESTACK
 
 MORESTACK:
-    pushl 8(%esp)           //              argsz > ra stksz argsz x x ra args
-    leal 28(%esp),%eax      //                argsz ra stksz argsz x x ra args
-    pushl %eax              //         argp > argsz ra stksz argsz x x ra args
-    pushl 12(%esp)          //   stksz > argp argsz ra stksz argsz x x ra args
-    calll RUST_NEW_STACK
-    addl $12,%esp           //                      ra stksz argsz x x ra args
-
-    movl (%esp),%edx        // Grab the return pointer.
-    incl %edx               // Skip past the `ret`.
-    movl %eax,%esp          // Switch to the new stack.
+
+    // Sanity check to make sure that there is a currently-running task.
+    subl $12,%esp
+    calll RUST_GET_TASK
+    testl %eax,%eax
+    jz L$bail
+
+    subl $12,%esp
+    pushl $12
+    calll UPCALL_ALLOC_C_STACK
+    movl %eax,%edx
+
+                            // C stack              | esp+12
+                            // ---------------------+-------------------------
+    movl 20(%esp),%eax      //                      | ra stksz argsz x ra args
+    movl %eax,8(%edx)       //              argsz > | ra stksz argsz x ra args
+    leal 32(%esp),%eax      //                argsz | ra stksz argsz x ra args
+    movl %eax,4(%edx)       //         argp > argsz | ra stksz argsz x ra args
+    movl 16(%esp),%eax      //           argp argsz | ra stksz argsz x ra args
+    movl %eax,(%edx)        //   stksz > argp argsz | ra stksz argsz x ra args
+
+    calll L$pic_ref_pt_0
+L$pic_ref_pt_0:
+    popl %eax
+
+    movl rust_new_stack_sym-L$pic_ref_pt_0(%eax),%eax
+    movl %eax,(%esp)
+    movl %edx,4(%esp)
+    calll UPCALL_CALL_C_STACK
+
+    movl 16(%esp),%edx          // Grab the return pointer.
+    addl $RETURN_OFFSET,%edx    // Skip past the `add esp,4` and the `ret`.
+
+    movl %eax,%esp          // Switch stacks.
+    subl $12,%esp           // Align the stack.
     calll *%edx             // Re-enter the function that called us.
 
     // Now the function that called us has returned, so we need to delete the
     // old stack space.
-    calll RUST_DEL_STACK
-    movl %eax,%esp
-    retl $8                 //                      ra stksz argsz x x ra args
+
+    calll RUST_GET_PREV_STACK
+    movl %eax,%esp          // Switch back to the old stack.
+
+    movl $0,(%esp)
+    calll UPCALL_ALLOC_C_STACK
+
+    calll L$pic_ref_pt_1
+L$pic_ref_pt_1:
+    popl %edx
+
+    movl rust_del_stack_sym-L$pic_ref_pt_1(%edx),%edx
+    movl %edx,(%esp)
+    movl %eax,4(%esp)
+    calll UPCALL_CALL_C_STACK
+
+    addl $16,%esp
+    retl $16 + ALIGNMENT    //                      ra stksz argsz x ra args
+
+L$bail:
+    movl 12(%esp),%edx
+    addl $RETURN_OFFSET,%edx
+    addl $12+16,%esp
+    jmpl *%edx
+
+#ifdef __APPLE__
+
+	.section	__IMPORT,__pointers,non_lazy_symbol_pointers
+rust_new_stack_sym:
+    .indirect_symbol RUST_NEW_STACK
+    .long 0
+rust_del_stack_sym:
+    .indirect_symbol RUST_DEL_STACK
+    .long 0
+
+#endif