Thanks for the report. Yep, the 4.01 code generator doesn't
generate correct code for _casm_GC_ expressions. This bug
was fixed some time ago (and will be included in 4.02)
It's available via the CVS repository should you depend
on having a working _ccall_GC_ impl right now though.

--Sigbjorn

> Manuel M. T. Chakravarty [mailto:[EMAIL PROTECTED]] writes: 
> 
> "Manuel M. T. Chakravarty" <[EMAIL PROTECTED]> wrote,
> 
> > If I link
> > 
> >   import Addr (Addr, nullAddr)
> > 
> >   foreign import ccall "foo" foo :: Int -> Addr -> IO ()
> > 
> >   main = foo (id 32) nullAddr
> > 
> > with
> > 
> >   void foo (int x, char *y)
> >   {
> >     printf ("foo: x = %d; y = %xl\n", x, (long) y);
> >   }
> > 
> > I get
> > 
> >   foo: x = 134516888; y = 0l
> 
> After closer inspection of the generated C code, I found an
> explanation of the problem.  The reason is a mistake in the
> C code generation for the primitive `_ccall_GC_'.  It
> becomes apparent when considering the C generated for
> 
>   foo x y = _ccall_GC_ foo x y
> 
> In STG, this turns into a case cascade including 
> 
>   {-_ccall-}__ccall_GC foo [c1nt x4 x6]
> 
> (this is an expression scrutinized in one of the case).  The
> C code emitted for this STG expression is
> 
>   IFN_(c1nF_ret) {
>         FB_
>         Sp[1]=(W_)((P_)&c1nG_info);
>         Sp=Sp+1;
>         {
>         I_ _ccall_arg1=(I_)(*Sp);
>         StgAddr _ccall_arg2=(StgAddr)(R1.p[1]);
>         do { SaveThreadState();
>         (foo((_ccall_arg1),(_ccall_arg2)));
>         LoadThreadState();} while(0);
>         }
>         JMP_(((P_)(*Sp)));
>         FE_
>   }
>   
> Unfortunately, the topmost stack location, where the
> (unboxed) first argument to `foo' sits is recycled and used
> for `&c1nG_info' before the line
> 
>         I_ _ccall_arg1=(I_)(*Sp);
> 
> extracts the value of the first argument.  So, the address
> of `c1nG_info' is passed to `foo' instead of the correct
> value. 
> 
> Hope this helps,
> 
> Manuel
> 

Reply via email to