From df4cb7a6ce45d7452a6ed74164742626d2aa232e Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 23 Sep 2008 00:24:41 -0400 Subject: [PATCH] fixed an off-by-one bug in ffi callbacks. --- scheme/last-revision | 2 +- src/ikarus-collect.c | 7 ++++--- src/ikarus-ffi.c | 50 ++++++++++++++++++++++++++++++++------------ 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/scheme/last-revision b/scheme/last-revision index 3c8cfd3..74d36ca 100644 --- a/scheme/last-revision +++ b/scheme/last-revision @@ -1 +1 @@ -1602 +1603 diff --git a/src/ikarus-collect.c b/src/ikarus-collect.c index 945c06d..cc181a0 100644 --- a/src/ikarus-collect.c +++ b/src/ikarus-collect.c @@ -795,16 +795,17 @@ add_code_entry(gc_t* gc, ikptr entry){ static void collect_stack(gc_t* gc, ikptr top, ikptr end){ if(DEBUG_STACK){ - fprintf(stderr, "collecting stack from 0x%016lx .. 0x%016lx\n", - (long) top, (long) end); + fprintf(stderr, "collecting stack (size=%ld) from 0x%016lx .. 0x%016lx\n", + (long)end - (long)top, (long) top, (long) end); } while(top < end){ if(DEBUG_STACK){ - fprintf(stderr, "collecting frame at 0x%016lx: ", (long) top); + fprintf(stderr, "collecting frame at 0x%016lx: \n", (long) top); } ikptr rp = ref(top, 0); long int rp_offset = unfix(ref(rp, disp_frame_offset)); if(DEBUG_STACK){ + fprintf(stderr, "rp=0x%016lx\n", rp); fprintf(stderr, "rp_offset=%ld\n", rp_offset); } if(rp_offset <= 0){ diff --git a/src/ikarus-ffi.c b/src/ikarus-ffi.c index 694174a..7eaac5e 100644 --- a/src/ikarus-ffi.c +++ b/src/ikarus-ffi.c @@ -128,10 +128,23 @@ ikrt_ffi_prep_cif(ikptr rtptr, ikptr argstptr, ikpcb* pcb) { } } -/* FIXME: handle stack overflow */ +static void +dump_stack(ikpcb* pcb, char* msg) { + fprintf(stderr, "==================== %s\n", msg); + ikptr frame_base = pcb->frame_base; + ikptr frame_pointer = pcb->frame_pointer; + ikptr p = frame_pointer; + fprintf(stderr, "fp=0x%016lx base=0x%016lx\n", frame_pointer, frame_base); + while(p < frame_base) { + fprintf(stderr, "*0x%016lx = 0x%016lx\n", p, ref(p, 0)); + p += wordsize; + } +} + +/* FIXME: handle stack overflow */ ikptr ikrt_seal_scheme_stack(ikpcb* pcb) { #if 0 @@ -155,6 +168,7 @@ ikrt_seal_scheme_stack(ikpcb* pcb) { ikptr frame_base = pcb->frame_base; ikptr frame_pointer = pcb->frame_pointer; #ifdef DEBUG_FFI + dump_stack(pcb, "BEFORE SEALING"); fprintf(stderr, "old base=0x%016lx fp=0x%016lx\n", pcb->frame_base, pcb->frame_pointer); #endif @@ -162,7 +176,7 @@ ikrt_seal_scheme_stack(ikpcb* pcb) { ikptr underflow_handler = ref(frame_base, -wordsize); cont* k = (cont*) pcb->next_k; cont* nk = (cont*) ik_unsafe_alloc(pcb, sizeof(cont)); - nk->tag = k->tag; + nk->tag = continuation_tag; nk->next = (ikptr) k; nk->top = frame_pointer; #ifdef DEBUG_FFI @@ -175,7 +189,7 @@ ikrt_seal_scheme_stack(ikpcb* pcb) { #endif pcb->next_k = vector_tag + (ikptr)nk; pcb->frame_base = frame_pointer; - pcb->frame_pointer = frame_pointer - wordsize; + pcb->frame_pointer = pcb->frame_base - wordsize; #ifdef DEBUG_FFI fprintf(stderr, "new base=0x%016lx fp=0x%016lx\n", pcb->frame_base, pcb->frame_pointer); @@ -187,12 +201,16 @@ ikrt_seal_scheme_stack(ikpcb* pcb) { fprintf(stderr, "already sealed\n"); #endif } +#ifdef DEBUG_FFI + dump_stack(pcb, "AFTER SEALING"); +#endif return void_object; } ikptr ikrt_call_back(ikptr proc, ikpcb* pcb) { ikrt_seal_scheme_stack(pcb); + ikptr old_k = pcb->next_k; pcb->next_k = 0; ikptr entry_point = ref(proc, off_closure_code); @@ -201,13 +219,13 @@ ikrt_call_back(ikptr proc, ikpcb* pcb) { fprintf(stderr, "system_stack = 0x%016lx\n", pcb->system_stack); #endif ikptr code_ptr = entry_point - off_code_data; + pcb->frame_pointer = pcb->frame_base; ikptr rv = ik_exec_code(pcb, code_ptr, 0, proc); #ifdef DEBUG_FFI fprintf(stderr, "system_stack = 0x%016lx\n", pcb->system_stack); #endif - ikptr rv2 = ref(pcb->frame_pointer, -2*wordsize); #ifdef DEBUG_FFI - fprintf(stderr, "rv=0x%016lx 0x%016lx\n", rv, rv2); + fprintf(stderr, "rv=0x%016lx\n", rv); #endif pcb->next_k = old_k; pcb->frame_pointer = pcb->frame_base - wordsize; @@ -215,7 +233,7 @@ ikrt_call_back(ikptr proc, ikpcb* pcb) { fprintf(stderr, "rp=0x%016lx\n", ref(pcb->frame_pointer, 0)); #endif pcb->system_stack = system_stack; - return rv2; + return rv; } @@ -224,6 +242,9 @@ ikptr ikrt_ffi_call(ikptr data, ikptr argsvec, ikpcb* pcb) { ikrt_seal_scheme_stack(pcb); + ikptr old_k = pcb->next_k; + pcb->next_k = 0; + ikptr system_stack = pcb->system_stack; ikptr cifptr = ref(data, off_vector_data + 0 * wordsize); ikptr funptr = ref(data, off_vector_data + 1 * wordsize); @@ -247,12 +268,13 @@ ikrt_ffi_call(ikptr data, ikptr argsvec, ikpcb* pcb) { free(avalues[i]); } #ifdef DEBUG_FFI - fprintf(stderr, "DONE WITH CALL, RV=0x%016lx 0x%016lx\n", - (long)val, - ref(pcb->frame_pointer, -2*wordsize)); + fprintf(stderr, "DONE WITH CALL, RV=0x%016lx\n", (long)val); #endif free(avalues); free(rvalue); + pcb->frame_pointer = pcb->frame_base - wordsize; + pcb->next_k = old_k; + pcb->system_stack = system_stack; return val; } @@ -300,20 +322,22 @@ generic_callback(ffi_cif *cif, void *ret, void **args, void *user_data){ ikptr code_ptr = code_entry - off_code_data; ikptr frame_pointer = pcb->frame_pointer; ikptr frame_base = pcb->frame_base; + /* if ((frame_base - wordsize) != frame_pointer) { fprintf(stderr, "ikarus internal error: INVALID FRAME LAYOUT 0x%016lx .. 0x%016lx\n", frame_base, frame_pointer); exit(-1); } - ref(frame_pointer, -2*wordsize) = fix(*((int*)args[0])); + */ + pcb->frame_pointer = pcb->frame_base; + ref(pcb->frame_pointer, -2*wordsize) = fix(*((int*)args[0])); ikptr rv = ik_exec_code(pcb, code_ptr, fix(-1), proc); - ikptr rv2 = ref(pcb->frame_pointer, -2*wordsize); #ifdef DEBUG_FFI - fprintf(stderr, "and back with rv=0x%016lx 0x%016lx!\n", rv, rv2); + fprintf(stderr, "and back with rv=0x%016lx!\n", rv); #endif pcb->system_stack = old_system_stack; pcb->next_k = old_next_k; - *((ikptr*)ret) = unfix(rv2); + *((ikptr*)ret) = unfix(rv); return; }