rt: Use an out pointer for rust_new_stack

upcall_call_shim_on_c_stack does not handle return values
This commit is contained in:
Brian Anderson 2011-12-05 17:11:33 -08:00
parent 98cd96ce96
commit 3b8bfaf534
3 changed files with 31 additions and 14 deletions

View file

@ -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

View file

@ -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

View file

@ -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