diff --git a/src/rt/arch/i386/morestack.S b/src/rt/arch/i386/morestack.S index 7b5446ae2357..30084ec2de0c 100644 --- a/src/rt/arch/i386/morestack.S +++ b/src/rt/arch/i386/morestack.S @@ -75,11 +75,12 @@ MORESTACK: // The arguments to rust_new_stack2 movl 40(%esp),%eax // Size of stack arguments - movl %eax,16(%esp) + movl %eax,20(%esp) leal 48(%esp),%eax // Address of stack arguments - movl %eax,12(%esp) + movl %eax,16(%esp) movl 36(%esp),%eax // The amount of stack needed - movl %eax,8(%esp) + movl %eax,12(%esp) + movl $0, 8(%esp) // Out pointer #ifdef __APPLE__ call 1f @@ -97,7 +98,7 @@ MORESTACK: movl 32(%esp),%edx // Grab the return pointer. inc %edx // Skip past the ret instruction in the parent fn - movl %eax,%esp // Switch stacks. + movl 8(%esp),%esp // Switch stacks. call *%edx // Re-enter the function that called us. // Now the function that called us has returned, so we need to delete the diff --git a/src/rt/arch/x86_64/morestack.S b/src/rt/arch/x86_64/morestack.S index 4147052345d6..ef0edcee7209 100644 --- a/src/rt/arch/x86_64/morestack.S +++ b/src/rt/arch/x86_64/morestack.S @@ -81,9 +81,12 @@ MORESTACK: movq %rbp, %rcx addq $24, %rcx // Base pointer, return address x2 + pushq $0 // Alignment + pushq %r11 // Size of stack arguments pushq %rcx // Address of stack arguments pushq %r10 // The amount of stack needed + pushq $0 // Out pointer movq UPCALL_NEW_STACK@GOTPCREL(%rip), %rsi movq %rsp, %rdi @@ -95,7 +98,8 @@ MORESTACK: #endif // Pop the new_stack_args struct - addq $24, %rsp + popq %rax + addq $32, %rsp // Pop the saved arguments popq %r9 diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index e6e89c62cc09..670dbc3a24a8 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -217,28 +217,40 @@ extern "C" void record_sp(void *limit); */ extern "C" CDECL void upcall_call_shim_on_c_stack(void *args, void *fn_ptr) { + rust_task *task = rust_scheduler::get_task(); + // FIXME (1226) - The shim functions generated by rustc contain the // morestack prologue, so we need to let them know they have enough // stack. - record_sp(0); - rust_task *task = rust_scheduler::get_task(); + //record_sp(0); + rust_scheduler *sched = task->sched; - sched->c_context.call_shim_on_c_stack(args, fn_ptr); - task->record_stack_limit(); + try { + sched->c_context.call_shim_on_c_stack(args, fn_ptr); + } catch (...) { + //task = rust_scheduler::get_task(); + //task->record_stack_limit(); + throw; + } + //task = rust_scheduler::get_task(); + //task->record_stack_limit(); } struct rust_new_stack2_args { - size_t stk_sz; - void *args_addr; - size_t args_sz; + void *new_stack; + size_t stk_sz; + void *args_addr; + size_t args_sz; }; // A new stack function suitable for calling through // upcall_call_shim_on_c_stack -extern "C" CDECL void * +extern "C" CDECL void upcall_new_stack(struct rust_new_stack2_args *args) { rust_task *task = rust_scheduler::get_task(); - return task->new_stack(args->stk_sz, args->args_addr, args->args_sz); + args->new_stack = task->new_stack(args->stk_sz, + args->args_addr, + args->args_sz); } extern "C" CDECL void