chicken-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-hackers] [PATCH] Fix an off-by-one size calculation error in co


From: Peter Bex
Subject: [Chicken-hackers] [PATCH] Fix an off-by-one size calculation error in compiler
Date: Sat, 23 May 2015 16:15:14 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

Hi all,

While working on the numbers-integration branch, I stumbled across a bug
that's been in CHICKEN for a while: when compiling something that involves
a call to (list ...), it will generate a call to the inline allocating C
function "C_a_i_list" with the calculated size of the number of items
times three.  Unfortunately, this is one word too short, as can be seen
from the following definition from chicken.h:

#define C_SIZEOF_LIST(n)          ((n) * 3 + 1)

Because it's "only" an off-by-one, it rarely causes issues (though it may
explain a few mysterious bugs).

A good example is the locative-stress-test:

If you look at the generated C code, it will have generated code to
allocate 90 words for storing a list of 10 items which are the result
of conversion from the C "long" type.  In the chicken-4 and master
branches, this will look like this:

/* k408 in loop in k475 in k383 in k303 in k300 in k297 in k294 */
static void C_ccall f_410(C_word c,C_word t0,C_word t1){
C_word tmp;
C_word t2;
C_word t3;
C_word t4;
C_word ab[70],*a=ab;
C_check_for_interrupt;
if(!C_stack_probe(&a)){
C_save_and_reclaim((void*)tr2,(void*)f_410,2,t0,t1);}
t2=C_a_i_list(&a,10,C_long_to_num(&a,*((long 
*)C_data_pointer(((C_word*)t0)[2]))),C_long_to_num(&a,*((long *)C_d
ata_pointer(((C_word*)t0)[3]))),C_long_to_num(&a,*((long 
*)C_data_pointer(((C_word*)t0)[4]))),C_long_to_num(&a,*
((long *)C_data_pointer(((C_word*)t0)[5]))),C_long_to_num(&a,*((long 
*)C_data_pointer(((C_word*)t0)[6]))),C_long
_to_num(&a,*((long 
*)C_data_pointer(((C_word*)t0)[7]))),C_long_to_num(&a,*((long 
*)C_data_pointer(((C_word*)t0)[
8]))),C_long_to_num(&a,*((long 
*)C_data_pointer(((C_word*)t0)[9]))),C_long_to_num(&a,*((long 
*)C_data_pointer(((
C_word*)t0)[10]))),C_long_to_num(&a,*((long 
*)C_data_pointer(((C_word*)t0)[11]))));
if(C_truep(C_i_equalp(t2,((C_word*)t0)[12]))){
t3=C_fixnum_difference(((C_word*)t0)[13],C_fix(1));
C_trace("locative-stress-test.scm:50: loop");
t4=((C_word*)((C_word*)t0)[14])[1];
f_400(t4,((C_word*)t0)[15],t3);}
else{
C_trace("locative-stress-test.scm:49: error");
((C_proc4)C_fast_retrieve_proc(*((C_word*)lf[3]+1)))(4,*((C_word*)lf[3]+1),((C_word*)t0)[15],lf[4],t2);}}

If you check the &a's, you'll see it only passes it to C_stack_probe
(which does not allocate), to C_a_i_list (which will use 31 words:
1 for the NIL at the end and 3 slots for each pair containing one
number) and to the 10 calls to C_long_to_num (which use up 4 words each,
as determined in the "long" part in estimate-foreign-result-size in
support.scm).

This gives us 31+40*1 = 71 words.  As you can see, it misses one word.
Usually this doesn't cause trouble, but it may trigger a bug when the
stack is lined up *just* so.  Attached are patches for the
numbers-scratchspace, chicken-5 and master branches.

Cheers,
Peter

Attachment: 0001-Fix-size-calculation-for-generated-code-for-list-CHICKEN-5.patch
Description: Text Data

Attachment: 0001-Fix-size-calculation-for-generated-code-for-list-MASTER.patch
Description: Text Data

Attachment: 0001-Fix-size-calculation-for-generated-code-for-list-NUMBERS-INTEGRATION-SCRATCHSPACE.patch
Description: Text Data

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]