"Sigbjorn Finne (Intl Vendor)" <[EMAIL PROTECTED]> wrote,

> 
> Manuel M. T. Chakravarty <[EMAIL PROTECTED]> writes: 
> > 
> .... 
> > > >   --(2) foreign import ccall "" "bar" bar :: IO Int64
> > > > 
> > > 
> > > this can be reduced to
> > > 
> > >      foreign import "bar" bar :: IO Int64
> > 
> > So, `ccall' is the default?  (This is not documented, I think.)
> > 
> 
> There's been some changes relatively recently, making the calling
> convention optional and dropping the requirement that a 'foreign
> import'ed function has got to be an IO action, i.e., you can now 
> write
>   
>    foreign import "sin" my_sin :: Float -> Float

This will save some `unsafePerformIO', but may be a trap for 
some beginners (but maybe beginners shouldn't play with this
anyway ;-)

> I'll see if I can put up a new version of the spec which reflects
> these changes.

That would be great.  Thank you.

> > > >   main = do
> > > >            foo (intToInt8 8) (intToInt16 16) (intToInt32 32) 
> > > > (intToInt64 64) 
> > > >   --(2)  _ <- bar
> > > >            return ()
> > > > 
> > > > The first problem is that `Int8', `Int16', and `Int32' are
> > > > all implemented by the same C data type, namely the one
> > > > represented by `I_' in the HC file -- this makes all of them
> > > > 32 bit `signed int' on my Pentium machine.  The generated HC 
> > > > code for the call to `foo' is
> > > > 
> > > 
> > > ghc does not currently make any attempts to provide and use a
> > > mapping from the Int* Haskell types onto equivalent C types.
> > > Why? Mainly because an Int8 is just represented as a differently
> > > boxed Int# - i.e., there's no sized Ints at the level of
> > > unboxed types.
> > > 
> > > You may get some warnings when compiling the above "foo", but
> > > the right coercions will be inserted, no?
> > 
> > It works with gcc on my Pentium, but I think it is pure
> > luck.  Unfortunately, I don't have a C reference manual at
> > the moment, but I think to recall that C doesn't do any
> > coercions during parameter passing -- it *definitely* won't
> > do any coercions if you don't supply a function prototype.
> > It works on my box only because gcc on the Pentium always
> > pushes a full 4-byte word even if you only pass a
> > character.  
> > 
> 
> The type promotions that apply when passing params in C
> are those that apply when assigning, i.e.,
> 
>     void shorty(short x);
>     short s; int i;
> 
>     s = i;
>     shorty(i);
> 
> I'm not so sure that it wouldn't work without prototypes,
> K&R C managed fine without them. However, maybe modern
> ABIs do now assume the presence of parameter type info
> to get things right all the time..

Ok, I found it (I mean my copy of K&R second edition).  When
there is a function prototype, coercions apply as you said.
However, if there is an old-style function declaration (and
this seems to include no function declaration) in scope,
integrals are promoted to int (or unsigned int).  In other
words,

  foo () 
  {
    ...
    shorty(i);  /* no declaration yet */
  }

  shorty(short x)
  {
    ...
  }

will cause trouble.  But this also means that it wouldn't
help if GHC emitted a cast in the FFI call.  If there is no
prototype, things will potentially go wrong...long live the
-#include option.

> > This may prove quite tricky to define in the FFI spec in a
> > portable manner -- but I guess, you are already aware of
> > that. 
> > 
> 
> Yes, it probably won't work with a native codegen either.
> It needs to be addressed at some stage by ghc.

Given the IntXX types, it should be ok when calling your own
routines, because you can also ensure on the C side that the
arguments have a fixed size.  However, it is tricky when
calling a library whose interface you can't control.  How
about providing types like `ForeignInt', which are
guaranteed by the implementation to be of the standard
integer size of the operating system on the given machine?
Then we could always import a C routine

  void foo (int x);

with

  foreign import "foo" foo :: ForeignInt -> IO ()

and use something like

  foo (intToForeignInt 42)

to call it.

Should work, shouldn't it?

Manuel

Reply via email to