mikepaul-LuaJIT/doc/ext_ffi_semantics.html

270 lines
9.1 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>FFI Semantics</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
</head>
<body>
<div id="site">
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1>FFI Semantics</h1>
</div>
<div id="nav">
<ul><li>
<a href="luajit.html">LuaJIT</a>
<ul><li>
<a href="install.html">Installation</a>
</li><li>
<a href="running.html">Running</a>
</li></ul>
</li><li>
<a href="extensions.html">Extensions</a>
<ul><li>
<a href="ext_ffi.html">FFI Library</a>
<ul><li>
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
</li><li>
<a href="ext_ffi_api.html">ffi.* API</a>
</li><li>
<a href="ext_ffi_int64.html">64 bit Integers</a>
</li><li>
<a class="current" href="ext_ffi_semantics.html">FFI Semantics</a>
</li></ul>
</li><li>
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
<ul><li>
<a href="changes.html">Changes</a>
</li></ul>
</li><li>
<a href="faq.html">FAQ</a>
</li><li>
<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
</li><li>
<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
</li></ul>
</div>
<div id="main">
<p>
TODO
</p>
<h2 id="clang">C Language Support</h2>
<p>
TODO
</p>
<h2 id="convert">C Type Conversion Rules</h2>
<p>
TODO
</p>
<h2 id="init">Initializers</h2>
<p>
Creating a cdata object with <a href="ffi_ext_api.html#ffi_new">ffi.new()</a>
or the equivalent constructor syntax always initializes its contents,
too. Different rules apply, depending on the number of optional
initializers and the C&nbsp;types involved:
</p>
<ul>
<li>If no initializers are given, the object is filled with zero bytes.</li>
<li>Scalar types (numbers and pointers) accept a single initializer.
The standard <a href="#convert">C&nbsp;type conversion rules</a>
apply.</li>
<li>Valarrays (complex numbers and vectors) are treated like scalars
when a single initializer is given. Otherwise they are treated like
regular arrays.</li>
<li>Aggregate types (arrays and structs) accept either a single
compound initializer (Lua table or string) or a flat list of
initializers.</li>
<li>The elements of an array are initialized, starting at index zero.
If a single initializer is given for an array, it's repeated for all
remaining elements. This doesn't happen if two or more initializers
are given: all remaining uninitialized elements are filled with zero
bytes.</li>
<li>The fields of a <tt>struct</tt> are initialized in the order of
their declaration. Uninitialized fields are filled with zero
bytes.</li>
<li>Only the first field of a <tt>union</tt> can be initialized with a
flat initializer.</li>
<li>Elements or fields which are aggregates themselves are initialized
with a <em>single</em> initializer, but this may be a compound
initializer or a compatible aggregate, of course.</li>
</ul>
<h2 id="clib">C Library Namespaces</h2>
<p>
A C&nbsp;library namespace is a special kind of object which allows
access to the symbols contained in libraries. Indexing it with a
symbol name (a Lua string) automatically binds it to the library.
</p>
<p>
TODO
</p>
<h2 id="ops">Operations on cdata Objects</h2>
<p>
TODO
</p>
<h2 id="gc">Garbage Collection of cdata Objects</h2>
<p>
All explicitly (<tt>ffi.new()</tt>, <tt>ffi.cast()</tt> etc.) or
implicitly (accessors) created cdata objects are garbage collected.
You need to ensure to retain valid references to cdata objects
somewhere on a Lua stack, an upvalue or in a Lua table while they are
still in use. Once the last reference to a cdata object is gone, the
garbage collector will automatically free the memory used by it (at
the end of the next GC cycle).
</p>
<p>
Please note that pointers themselves are cdata objects, however they
are <b>not</b> followed by the garbage collector. So e.g. if you
assign a cdata array to a pointer, you must keep the cdata object
holding the array alive as long as the pointer is still in use:
</p>
<pre class="code">
ffi.cdef[[
typedef struct { int *a; } foo_t;
]]
local s = ffi.new("foo_t", ffi.new("int[10]")) -- <span style="color:#c00000;">WRONG!</span>
local a = ffi.new("int[10]") -- <span style="color:#00a000;">OK</span>
local s = ffi.new("foo_t", a)
-- Now do something with 's', but keep 'a' alive until you're done.
</pre>
<p>
Similar rules apply for Lua strings which are implicitly converted to
<tt>"const&nbsp;char&nbsp;*"</tt>: the string object itself must be
referenced somewhere or it'll be garbage collected eventually. The
pointer will then point to stale data, which may have already beeen
overwritten. Note that string literals are automatically kept alive as
long as the function containing it (actually its prototype) is not
garbage collected.
</p>
<p>
Objects which are passed as an argument to an external C&nbsp;function
are kept alive until the call returns. So it's generally safe to
create temporary cdata objects in argument lists. This is a common
idiom for passing specific C&nbsp;types to vararg functions:
</p>
<pre class="code">
ffi.cdef[[
int printf(const char *fmt, ...);
]]
ffi.C.printf("integer value: %d\n", ffi.new("int", x)) -- <span style="color:#00a000;">OK</span>
</pre>
<p>
Memory areas returned by C functions (e.g. from <tt>malloc()</tt>)
must be manually managed, of course. Pointers to cdata objects are
indistinguishable from pointers returned by C functions (which is one
of the reasons why the GC cannot follow them).
</p>
<h2 id="status">Current Status</h2>
<p>
The initial release of the FFI library has some limitations and is
missing some features. Most of these will be fixed in future releases.
</p>
<p>
<a href="#clang">C language support</a> is
currently incomplete:
</p>
<ul>
<li>C&nbsp;declarations are not passed through a C&nbsp;pre-processor,
yet.</li>
<li>The C&nbsp;parser is able to evaluate most constant expressions
commonly found in C&nbsp;header files. However it doesn't handle the
full range of C&nbsp;expression semantics and may fail for some
obscure constructs.</li>
<li><tt>static const</tt> declarations only work for integer types
up to 32&nbsp;bits. Neither declaring string constants nor
floating-point constants is supported.</li>
<li>The <tt>long double</tt> C&nbsp;type is parsed correctly, but
there's no support for the related conversions, accesses or
arithmetic operations.</li>
<li>Packed <tt>struct</tt> bitfields that cross container boundaries
are not implemented.</li>
<li>Native vector types may be defined with the GCC <tt>mode</tt> and
<tt>vector_size</tt> attributes. But no operations other than loading,
storing and initializing them are supported, yet.</li>
<li>The <tt>volatile</tt> type qualifier is currently ignored by
compiled code.</li>
<li><a href="ext_ffi_api.html#ffi_cdef">ffi.cdef</a> silently ignores
all redeclarations.</li>
</ul>
<p>
The JIT compiler already handles a large subset of all FFI operations.
It automatically falls back to the interpreter for unimplemented
operations (you can check for this with the
<a href="running.html#opt_j"><tt>-jv</tt></a> command line option).
The following operations are currently not compiled and may exhibit
suboptimal performance, especially when used in inner loops:
</p>
<ul>
<li>Array/<tt>struct</tt> copies and bulk initializations.</li>
<li>Bitfield accesses and initializations.</li>
<li>Vector operations.</li>
<li>Lua tables as compound initializers.</li>
<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>
<li>Allocations of variable-length arrays or structs.</li>
<li>Allocations of C&nbsp;types with a size &gt; 64&nbsp;bytes or an
alignment &gt; 8&nbsp;bytes.</li>
<li>Conversions from <tt>lightuserdata</tt> to <tt>void&nbsp;*</tt>.</li>
<li>Pointer differences for element sizes that are not a power of
two.</li>
<li>Calls to non-cdecl or vararg C&nbsp;functions.</li>
<li>Calls to C&nbsp;functions with aggregates passed or returned by
value.</li>
<li>Calls to C&nbsp;functions with 64 bit arguments or return values
on 32 bit CPUs.</li>
<li><tt>tostring()</tt> for cdata types.</li>
<li>The following <a href="ext_ffi_api.html">ffi.* API</a> functions:
<tt>ffi.sizeof()</tt>, <tt>ffi.alignof()</tt>, <tt>ffi.offsetof()</tt>.
</ul>
<p>
Other missing features:
</p>
<ul>
<li>Bit operations for 64&nbsp;bit types.</li>
<li>Arithmetic for <tt>complex</tt> numbers.</li>
<li>User-defined metamethods for C&nbsp;types.</li>
<li>Callbacks from C&nbsp;code to Lua functions.</li>
<li>Atomic handling of <tt>errno</tt>.</li>
<li>Passing structs by value to vararg C&nbsp;functions.</li>
<li><a href="extensions.html#exceptions">C++ exception interoperability<a/>
does not extend to C&nbsp;functions called via the FFI.</li>
</ul>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2011 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>