<div dir="ltr">Hello,<div><br></div><div>just as another data point: I'd also find this functionality useful.  I've run into the problem when trying to bind to C libraries that have functions with struct parameters being passed by value, or returned (the idea being that under the hood these structs often end up split up across registers).   In the library I was working with, colors were implemented as RGBA structs which were passed and returned by value all over the place.</div>
<div><br></div><div>-Iavor</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Jun 14, 2014 at 8:57 AM, Yuras Shumovich <span dir="ltr"><<a href="mailto:shumovichy@gmail.com" target="_blank">shumovichy@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
I implemented support for returning C structures by value in cmm for<br>
x86_64 (most likely it works only on linux). You can find it here:<br>
<a href="https://github.com/Yuras/ghc/commits/cmm-cstruct" target="_blank">https://github.com/Yuras/ghc/commits/cmm-cstruct</a><br>
<br>
It supports I8, I16, I32, I64, F_, D_ cmm types, and  requires special<br>
annotation. For example:<br>
<br>
#include "Cmm.h"<br>
<br>
#define MyStruct struct(CInt, I8, struct(I8, CInt))<br>
<br>
cmm_test(W_ i)<br>
{<br>
  CInt i1;<br>
  I8 i2, i3;<br>
  float32 i4;<br>
  (i1, i2, i3, i4) = ccall c_test(W_TO_INT(i)) MyStruct;<br>
  return (TO_W_(i1), TO_W_(i2), TO_W_(i3), i4);<br>
}<br>
<br>
(See "test" directory for full examples.)<br>
<br>
<br>
Do you think it is right approach?<br>
Could anyone review the code please?<br>
<br>
And the last thing, I need mentor for this project. Is anyone interested?<br>
<br>
Thanks,<br>
Yuras<br>
<div class="HOEnZb"><div class="h5"><br>
On Tue, 2014-03-18 at 21:30 +0000, Simon Marlow wrote:<br>
> So the hard parts are:<br>
><br>
>   - the native code generators<br>
>   - native adjustor support (rts/Adjustor.c)<br>
><br>
> Everything else is relatively striaghtforward: we use libffi for<br>
> adjustors on some platforms and for GHCi, and the LLVM backend should be<br>
> quite easy too.<br>
><br>
> I would at least take a look at the hard bits and see whether you think<br>
> it's going to be possible to extend these to handle struct args/returns.<br>
>   Because if not, then the idea is a dead end.  Or maybe we will need to<br>
> limit the scope to make things easier (e.g. only integer and pointer<br>
> fields).<br>
><br>
> Cheers,<br>
> Simon<br>
><br>
> On 18/03/2014 17:31, Yuras Shumovich wrote:<br>
> > Hi,<br>
> ><br>
> > I thought I have lost the battle :)<br>
> > Thank you for the support, Simon!<br>
> ><br>
> > I'm interested in full featured solution: arguments, return value,<br>
> > foreign import, foreign export, etc. But it is too much for me to do it<br>
> > all at once. So I started with dynamic wrapper.<br>
> ><br>
> > The plan is to support structs as arguments and return value for dynamic<br>
> > wrapper using libffi;<br>
> > then implement native adjustors at least for x86_64 linux;<br>
> > then make final design decision (tuple or data? language pragma? union<br>
> > support? etc);<br>
> > and only then start working on foreign import.<br>
> ><br>
> > But I'm open for suggestions. Just let me know if you think it is better<br>
> > to start with return value support for foreign import.<br>
> ><br>
> > Thanks,<br>
> > Yuras<br>
> ><br>
> > On Tue, 2014-03-18 at 12:19 +0000, Simon Marlow wrote:<br>
> >> I'm really keen to have support for returning structs in particular.<br>
> >> Passing structs less so, because working around the lack of struct<br>
> >> passing isn't nearly as onerous as working around the lack of struct<br>
> >> returns.  Returning multiple values from a C function is a real pain<br>
> >> without struct returns: you have to either allocate some memory in<br>
> >> Haskell or in C, and both methods are needlessly complex and slow.<br>
> >> (though allocating in Haskell is usually better.) C++ code does this all<br>
> >> the time, so if you're wrapping C++ code for calling from Haskell, the<br>
> >> lack of multiple returns bites a lot.<br>
> >><br>
> >> In fact implementing this is on my todo list, I'm really glad to see<br>
> >> someone else is planning to do it :-)<br>
> >><br>
> >> The vague plan I had in my head was to allow the return value of a<br>
> >> foreign import to be a tuple containing marshallable types, which would<br>
> >> map to the appropriate return convention for a struct on the current<br>
> >> platform.  Perhaps allowing it to be an arbitrary single-constructor<br>
> >> type is better, because it allows us to use a type that has a Storable<br>
> >> instance.<br>
> >><br>
> >> Cheers,<br>
> >> Simon<br>
> >><br>
> ><br>
> ><br>
<br>
<br>
_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/ghc-devs" target="_blank">http://www.haskell.org/mailman/listinfo/ghc-devs</a><br>
</div></div></blockquote></div><br></div>