
Hi,
On Wed, Jun 25, 2014 at 12:58 PM, Mihaly Barasz
1. Is this actually OK to do? I guess that this wouldn't be OK if the foreign import were "safe", as then the GC could move the contents of the byte array while the foreign function is running. But is it safe like this?
Whether the foreign import is marked as safe or not doesn't matter. The GC might move the array just after you make your address computation but before the call is made. This is only safe if the Primitive array is guaranteed to be pinned. I checked the docs for that module and couldn't see any such promise.
2. If the answer to the previous question is no, then is there a way to do it properly? Or there is just no way to pass an unpinned byte array to a foreign call? What about foreign import prim?
There is a way to pass an unpinned ByteArray# (or MutableByteArray#, but the former seems right in your case) to a foreign call, using the UnliftedFFITypes language extension. The ByteArray# is guaranteed to not to be moved for the duration of the call. The code should treat the ByteArray# argument as if it was a pointer to bytes. You will need to do any address offset computations on the C side (i.e. pass any offsets you need as extra argument to your C function).
3. If the answer to Q1 is no, then would it be OK if the underlying byte array were pinned?
Yes, but I don't know if you can have the API give you any such guarantees, unless you use the Storable vector version.
4. Any other simplifications?
The unsafeThat bothers me. Doesn't vector give you any other way to get to the underlying ByteArray#? -- Johan