fixed an off-by-one bug in ffi callbacks.

This commit is contained in:
Abdulaziz Ghuloum 2008-09-23 00:24:41 -04:00
parent 09657334c0
commit df4cb7a6ce
3 changed files with 42 additions and 17 deletions

View File

@ -1 +1 @@
1602
1603

View File

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

View File

@ -128,10 +128,23 @@ ikrt_ffi_prep_cif(ikptr rtptr, ikptr argstptr, ikpcb* pcb) {
}
}
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;
}