lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Thu, Nov 10, 2011 at 10:35 AM, Miles Bader <miles@gnu.org> wrote:
> Jay Carlson <nop@nop.com> writes:

>>> LuaFFI isn't portable though; is alien?
>>
>> What do you mean by portable?
>
> What you (probably) think: can be compiled any system that Lua can.

Then no, since Lua aspires to compile and work on any ANSI C machine.
I think it's important to understand this limit. Many things many wish
to do cannot be accomplished within that constraint. In my opinion a
more important question is how much work a port of an extension
requires per platform/flavor, and what other costs it imposes.

>> I thought it was impossible in ANSI C to write Lisp's apply--that is,
>> call an arbitrary function with an arbitrary list of arguments. The
>> signature must be known at compile-time.[1] Now that I think of it,
>> ANSI C has no runtime type information anyway so it is impossible to
>> even describe the argument list.
>
> No doubt, but thus my question:  what does alien do?

It is a mystery.

> [...] While it may be impossible
> to completely support everything FFI does portably, maybe there are
> useful subsets, or alternative interfaces, which _can_ be done portably

You need to compile and link code, since under the portability
constraint (as we're discussing it) only the compiler understands the
ABI. Similarly, libffi cannot be portable; machine-specific code must
be written for each ABI. (As Steve points out this has already been
done well for most common and uncommon platforms.)

I can see one shortcut, although I'm not really a C language lawyer.
Any function with signature X may be called through a pointer to a
function with compatible signature X. It's not necessary to have one C
stub per function linked to; it suffices to have one per compatible
signature. If you do have additional (non-portable) knowledge about
the platform, it may be possible to merge more stubs; one case is if
you know a pointer to an int is passed in the same way as a pointer to
a struct.

> For instance, the sizes of C
> types can be discovered by a C program.

This is more complicated than it looks. When you compile
printf("%zu",sizeof(int)) it references a size_t constant, which is
printed at runtime. But at runtime there's no function
sizeof_type_name("int") to return 8. What would be quite useful is
sizeof_type_name("FILE") to return 148, or after dynamically loading
libpng12, sizeof_type_name("struct png_text_struct"). This information
is in the debugging symbols, but they are usually stripped from
binaries delivered to users; historically debug info was very
different from platform to platform. Instead of writing a C
declaration parser, browsing debug information may have some merit
though.

In a traditional self-hosted build process you can write a program
that prints the sizeof all the types you care about and then generate
C code based on that. But in cross-compilation environments, you may
not have the ability to run code you compile. At some point autoconf
gained the ability to deduce compile-time constants at by...declaring
an array of size 1-2*!(expr). If expr is false, the size of the array
is -1, and the compile fails. autoconf then does a *BINARY SEARCH* of
the integers for the value....

Jay
(why yes I did have to look up the C99 size_t qualifier for printf,
and then I still wrote "%zd", which is incorrect because size_t is
unsigned.)