[erlang-questions] Closure-based FFI

Alceste Scalas alceste@REDACTED
Fri Sep 14 09:47:50 CEST 2007

Il giorno gio, 13/09/2007 alle 17.36 +0100, David Hopwood ha scritto:
> Tagging pointers makes sense, but the representation of a pointer
> value need not be specified.

I think that a FFI should allow the developer to work as near as
possible to the "bare metal" (i.e. the underlying representation of the
C types).  It should be possible, thus, to see pointers as unsigned
integers --- that could be considered just opaque references when one
does not want to fiddle with them.  Other safety layers (like the
type-tagged interface) could be used as well.

> Tagging integer types makes less sense, I think; instead the FFI should
> check that the actual value of the integer falls within the range of
> its C type (see below for an interface that would support this).

I think that, when maximum FFI safety is required, a way to "mimic" the
C static typing would help, and would make bug hunting easier.  For
example, let's say I'm trying to use a uint32 value (returned by a FFI
call) as a sint16 C function parameter, without an explicit "cast": type
tagging would make the program fail immediately; range checking alone
could leave the bug hidden, until the value ranges are actually broken.

IMHO, type-tags could be used *together* with type range checks [1], in
order to ensure that {TypeTag, Value} tuples are actually consistent.

> ffi:c_function(port(), type_tag(), atom(), [type_tag()]) -> fun()
>       type_tag() = uchar|schar|...|pointer|nonnull|size_t|ssize_t
> C_malloc = ffi:c_function(Port, nonnull, malloc, [size_t]),
> C_free   = ffi:c_function(Port, void, free, [pointer]),
> C_memset = ffi:c_function(Port, void, memset,
>                                         [nonnull, int, size_t]),
> C_memcpy = ffi:c_function(Port, void, memcpy, [nonnull, nonnull, size_t])

Well, this closure-based FFI could be extremely elegant...  But I don't
see how it could be actually used.  Should a developer pass the FFI
closures around as function arguments?  Or redefine them in every
function before using them?  (I hope I'm not missing something very
obvious here).

> 'nonnull' means a pointer that is checked by the FFI to be non-NULL,
> i.e. an Erlang exception will be thrown if a NULL pointer is passed or
> returned.

Adding this FFI type is a good idea (IMHO).




  [1] Range checking is quite expensive, expecially when dealing with
      Erlang big integers.  The current, low-level FFI implementation
      does *not* check type ranges, but behaves mostly like C: only
      sizeof(CType) bytes of the function call arguments are considered.

Alceste Scalas <alceste@REDACTED>
CRS4 - http://www.crs4.it/

More information about the erlang-questions mailing list