Common FFI declarations

  • From: Mike Pall <mike-1205@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Tue, 8 May 2012 16:09:19 +0200

To cut the other thread ("LuaJIT Wiki") short:

Yes, I realize we need a couple of common FFI declarations to
avoid the redeclaration mess. And yes, they probably should be
shipped and installed with the LuaJIT core, because almost
everyone will need them to do anything useful.

The first one that comes to mind are the basic types for the WIN32
API. Not sure whether to split these up. There are plenty of types
that only make sense if you declare the related functions, too.
Luckily, the WIN32 types are cast in stone and they don't change
that much for Windows/x64. This probably needs to be designed
along a somewhat complete WIN32 binding (which should go into an
extra module, not shipped with the core).

The second one are the standard POSIX types. That's what you get
from <sys/types.h>. Maybe a couple more, like <dirent.h>. I'm open
to suggestions.

There are some tricky problems to solve, though: the actual types
may differ wildly between POSIX platforms, e.g. time_t or off_t.
And off_t changes with _FILE_OFFSET_BITS=64 and _LARGEFILE_SOURCE,
which is the setting that LuaJIT itself is built with. I guess it
would make sense to always define these as the 64 bit variant, but
then you'll need to use the correct libc calls (e.g. lseek64
instead of lseek). And of course this doesn't work the same on all
supported platforms (e.g. Linux vs. Android, Linux vs. *BSD).

Sadly, it's not that easy to automatically generate the target
definitions. With a cross-compiler you can't run the target
program. And the host compiler may not grok the target includes.
So one probably has to parse the output of $(CROSS)$(CC) -E and
grab only the needed definitions, but without all of the internal
cruft. Dunno whether it would be easier to do by hand or not for
the twenty-odd supported platform/arch combinations.

[Due to the restructured build process after beta10, there's always
have a customized, minimized Lua interpreter available (compiled
for the host). That's meant for running DynASM, but it's of course
reusable to generate or mangle some FFI modules at build time.]

And then there's the distro aspect. This demands that anything in
/usr/share/... (where the Lua modules reside) is portable and can
be shared across architectures. That's certainly achievable for
(say) Debian, but requires some extra mangling to properly use
platform-dependent types like size_t or intptr_t.

And far, far ahead there's also the C++ aspect: if we ever want to
interface with C++, then name mangling demands that e.g. 'long' be
preserved. You get different mangled symbol names for foo(int) vs.
foo(long), even if the two arguments happen to have the same size
on a platform. So the system types have to use _exactly_ the same
declarations as the C++ compiler sees.

--Mike

Other related posts: