chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] c-string return question


From: Jörg F . Wittenberger
Subject: Re: [Chicken-users] c-string return question
Date: 13 Oct 2011 22:07:28 +0200

John,

it's not my intention to argue about the merits of the way the
foreign-lambda* I posted has been written.
(If I had to do so, I would argue that using a dynamic "buf"
would be better style.  Less sensible to being [re]used in a
multi threaded or reentrant environment.)

My point is, that this code is valid wrt. the manual and apparently
valid given my understanding of what the C code tries to do:
make it possible to return on stack strings.

The compiler output could be much simpler, if there where a restriction
that c-string would always point to heap or static memory.
(Maybe a c-string-static type would be an idea to distinguish
the complex case and the simple one?  Not sure.)

The situation is, that more recent gcc versions will do fine with that
one (and break elsewhere) while those in some common linux distributions
at fail to work.

On Oct 13 2011, John Cowan wrote:

I looked at all instances of 'define return' and at most they seem to
copy pointers:

That's what they do.  They arrange things for ##sys#peek-c-string
to find the C string.

For me it ends up like this:

--------------- #define return(x) C_cblock C_r = (C_mpointer(&C_a,(void*)(x))); goto C_ret; C_cblockend static C_word C_fcall stub26(C_word C_buf,C_word C_a0) C_regparm; C_regparm static C_word C_fcall stub26(C_word C_buf,C_word C_a0){ C_word C_r=C_SCHEME_UNDEFINED,*C_a=(C_word*)C_buf; unsigned int ch=(unsigned int )C_num_to_unsigned_int(C_a0); static unsigned char off[6]={0xFC,0xF8,0xF0,0xE0,0xC0,0x00};
 int size=5; C_char buf[7];
 buf[6]='\0';
 if (ch < 0x80) {
   buf[5]=ch;
 } else {
   buf[size--]=(ch&0x3F)|0x80; ch=ch>>6;
   while (ch) { buf[size--]=(ch&0x3F)|0x80; ch=ch>>6; }
   /* Write the size information into the first byte */
   ++size;
   buf[size]=off[size]|buf[size];
 }
 return(buf+size);

C_ret:
#undef return

return C_r;}
---------------

to be called like this:

---------
t3=C_a_i_bytevector(&a,1,C_fix(3));
t4=C_i_foreign_unsigned_integer_argumentp(t2);
t5=stub26(t3,t4);
C_trace("##sys#peek-c-string");
t6=*((C_word*)lf[5]+1);
((C_proc4)(void*)(*((C_word*)t6+1)))(4,t6,t1,t5,C_fix(0));}
---------

But somehow the "C_proc4" receives clobbered memory.

I don't see why.

/Jörg







reply via email to

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