Cleanup of docs.

This commit is contained in:
Mike Pall 2011-02-11 13:50:01 +01:00
parent a5aade2fa9
commit 1f0006ac71
8 changed files with 157 additions and 75 deletions

View File

@ -256,7 +256,7 @@ to avoid joining by the compiler/linker.</li>
<li>Merged with Lua 5.1.1. Fixes all
<a href="http://www.lua.org/bugs.html#5.1"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1</a>.</li>
<li>Enforce (dynamic) linker error for EXE/DLL version mismatches.</li>
<li>Minor changes to DynASM: faster preprocessing, smaller encoding
<li>Minor changes to DynASM: faster pre-processing, smaller encoding
for some immediates.</li>
</ul>
<p>

View File

@ -8,6 +8,12 @@
<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">
<style type="text/css">
span.codemark { position:absolute; left: 16em; color: #4040c0; }
span.mark { color: #4040c0; font-family: Courier New, Courier, monospace;
line-height: 1.1; }
pre.mark { padding-left: 2em; }
</style>
</head>
<body>
<div id="site">
@ -55,16 +61,20 @@
</div>
<div id="main">
<p>
The FFI library allows calling external C&nbsp;functions and the use
of C&nbsp;data structures from pure Lua code.
The FFI library allows <b>calling external C&nbsp;functions</b> and
<b>using C&nbsp;data structures</b> from pure Lua code.
</p>
<p>
The FFI library largely obviates the need to write tedious manual
Lua/C bindings in C. It doesn't require learning a separate binding
language &mdash; it parses plain C&nbsp;declarations, which can be
Lua/C bindings in C. No need to learn a separate binding language
&mdash; <b>it parses plain C&nbsp;declarations!</b> These can be
cut-n-pasted from C&nbsp;header files or reference manuals. It's up to
the task of binding large libraries without the need for dealing with
fragile binding generators.
</p>
<p>
The FFI library is tightly integrated into LuaJIT (it's not available
@ -83,26 +93,30 @@ Please use the FFI sub-topics in the navigation bar to learn more.
<p>
It's really easy to call an external C&nbsp;library function:
</p>
<pre class="code">
local ffi = require("ffi") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9312;</span>
ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">&#9313;</span>
<pre class="code mark">
<span class="codemark">&#9312;
&#9313;
&#9314;</span>local ffi = require("ffi")
ffi.cdef[[
<span style="color:#00a000;">int printf(const char *fmt, ...);</span>
]]
ffi.C.printf("Hello %s!", "world") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
ffi.C.printf("Hello %s!", "world")
</pre>
<p>
So, let's pick that apart:
</p>
<p>
<span style="color:#4040c0;">&#9312;</span> Load the FFI library.
<span class="mark">&#9312;</span> Load the FFI library.
</p>
<p>
<span style="color:#4040c0;">&#9313;</span> Add a C&nbsp;declaration
<span class="mark">&#9313;</span> Add a C&nbsp;declaration
for the function. The part inside the double-brackets (in green) is
just standard C&nbsp;syntax.
</p>
<p>
<span style="color:#4040c0;">&#9314;</span> Call the named
<span class="mark">&#9314;</span> Call the named
C&nbsp;function &mdash; Yes, it's that simple!
</p>
<p style="font-size: 8pt;">
@ -198,25 +212,42 @@ need of a simple example ...
And here's the FFI version. The modified parts have been marked in
bold:
</p>
<pre class="code">
<b>local ffi = require("ffi")</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9312;</span>
<b>ffi.cdef[[
<pre class="code mark">
<span class="codemark">&#9312;
&#9313;
&#9314;
&#9315;
&#9314;
&#9316;</span><b>local ffi = require("ffi")
ffi.cdef[[
</b><span style="color:#00a000;">typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;</span><b>
]]</b>
local function image_ramp_green(n)
<b>local img = ffi.new("rgba_pixel[?]", n)</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9313;</span>
<b>local img = ffi.new("rgba_pixel[?]", n)</b>
local f = 255/(n-1)
for i=<b>0,n-1</b> do <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
<b>img[i].green = i*f</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9315;</span>
for i=<b>0,n-1</b> do
<b>img[i].green = i*f</b>
<b>img[i].alpha = 255</b>
end
return img
end
local function image_to_grey(img, n)
for i=<b>0,n-1</b> do <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9316;</span>
for i=<b>0,n-1</b> do
local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b>
img[i].red = y; img[i].green = y; img[i].blue = y
end
end
@ -231,30 +262,30 @@ end
Ok, so that wasn't too difficult:
</p>
<p>
<span style="color:#4040c0;">&#9312;</span> First, load the FFI
<span class="mark">&#9312;</span> First, load the FFI
library and declare the low-level data type. Here we choose a
<tt>struct</tt> which holds four byte fields, one for each component
of a 4x8&nbsp;bit RGBA pixel.
</p>
<p>
<span style="color:#4040c0;">&#9313;</span> Creating the data
<span class="mark">&#9313;</span> Creating the data
structure with <tt>ffi.new()</tt> is straightforward &mdash; the
<tt>'?'</tt> is a placeholder for the number of elements of a
variable-length array.
</p>
<p>
<span style="color:#4040c0;">&#9314;</span> C&nbsp;arrays are
<span class="mark">&#9314;</span> C&nbsp;arrays are
zero-based, so the indexes have to run from <tt>0</tt> to
<tt>n-1</tt>. One might want to allocate one more element instead to
simplify converting legacy code.
</p>
<p>
<span style="color:#4040c0;">&#9315;</span> Since <tt>ffi.new()</tt>
<span class="mark">&#9315;</span> Since <tt>ffi.new()</tt>
zero-fills the array by default, we only need to set the green and the
alpha fields.
</p>
<p>
<span style="color:#4040c0;">&#9316;</span> The calls to
<span class="mark">&#9316;</span> The calls to
<tt>math.floor()</tt> can be omitted here, because floating-point
numbers are already truncated towards zero when converting them to an
integer. This happens implicitly when the number is stored in the

View File

@ -316,7 +316,7 @@ bytes of the string <em>plus a zero-terminator</em> are copied to
</p>
<p>
Performance notice: <tt>ffi.copy()</tt> may be used as a faster
(inlineable) replacement for the C&nbsp;library functions
(inlinable) replacement for the C&nbsp;library functions
<tt>memcpy()</tt>, <tt>strcpy()</tt> and <tt>strncpy()</tt>.
</p>
@ -328,7 +328,7 @@ zero-filled.
</p>
<p>
Performance notice: <tt>ffi.fill()</tt> may be used as a faster
(inlineable) replacement for the C&nbsp;library function
(inlinable) replacement for the C&nbsp;library function
<tt>memset(dst,&nbsp;c,&nbsp;len)</tt>. Please note the different
order of arguments!
</p>

View File

@ -66,9 +66,9 @@ and its interaction with both Lua and C&nbsp;code.
</p>
<p>
Given that the FFI library is designed to interface with C&nbsp;code
and that declarations can be written in plain C&nbsp;syntax, it
closely follows the C&nbsp;language semantics, wherever possible. Some
minor concessions are needed for smoother interoperation with Lua
and that declarations can be written in plain C&nbsp;syntax, <b>it
closely follows the C&nbsp;language semantics</b>, wherever possible.
Some minor concessions are needed for smoother interoperation with Lua
language semantics.
</p>
<p>
@ -83,9 +83,8 @@ background.
Please note: this is the first public release of the FFI library. This
does not comprise the final specification for the FFI semantics, yet.
Some of the semantics may need to be changed, based on feedback from
developers. Please <a href="contact.html">report</a> any problems
you've encountered or any improvements you'd like to see &mdash; thank
you!
developers. Please <a href="contact.html">report</a> any problems you
may encounter or any improvements you'd like to see &mdash; thank you!
</p>
<h2 id="clang">C Language Support</h2>
@ -204,7 +203,7 @@ The following C&nbsp;features are <b>not</b> supported:
default to an <tt>int</tt> type.</li>
<li>Old-style empty function declarations (K&amp;R) are not allowed.
All C&nbsp;functions must have a proper protype declaration. A
All C&nbsp;functions must have a proper prototype declaration. A
function declared without parameters (<tt>int&nbsp;foo();</tt>) is
treated as a function taking zero arguments, like in C++.</li>
@ -312,7 +311,7 @@ C&nbsp;type of the destination, the
are applied.
</p>
<p>
Reference types are immutable after initialization ("no reseating of
Reference types are immutable after initialization ("no re-seating of
references"). For initialization purposes or when passing values to
reference parameters, they are treated like pointers. Note that unlike
in C++, there's no way to implement automatic reference generation of
@ -652,8 +651,8 @@ variable argument part of vararg C&nbsp;function use
<a href="#convert_vararg">special conversion rules</a>. This
C&nbsp;function is called and the return value (if any) is
<a href="#convert_tolua">converted to a Lua object</a>.<br>
On Windows/x86 systems, <tt>stdcall</tt> functions are automatically
detected and a function declared as <tt>cdecl</tt> (the default) is
On Windows/x86 systems, <tt>__stdcall</tt> functions are automatically
detected and a function declared as <tt>__cdecl</tt> (the default) is
silently fixed up after the first call.</li>
</ul>
@ -790,7 +789,7 @@ local s = ffi.new("foo_t", a)
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
pointer will then point to stale data, which may have already been
overwritten. Note that <em>string literals</em> are automatically kept
alive as long as the function containing it (actually its prototype)
is not garbage collected.
@ -951,7 +950,7 @@ 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"><tt>ffi.cdef</tt></a> silently
ignores all redeclarations.</li>
ignores all re-declarations.</li>
</ul>
<p>
The JIT compiler already handles a large subset of all FFI operations.

View File

@ -9,7 +9,12 @@
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
<style type="text/css">
span.codemark { position:absolute; left: 16em; color: #4040c0; }
span.mark { color: #4040c0; font-family: Courier New, Courier, monospace;
line-height: 1.1; }
pre.mark { padding-left: 2em; }
table.idiomtable { line-height: 1.2; }
table.idiomtable tt { font-size: 100%; }
tr.idiomhead td { font-weight: bold; }
td.idiomc { width: 12em; }
td.idiomlua { width: 14em; }
@ -94,27 +99,46 @@ The following code explains how to access standard system functions.
We slowly print two lines of dots by sleeping for 10&nbsp;milliseconds
after each dot:
</p>
<pre class="code">
local ffi = require("ffi")
ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">&#9312;</span>
<pre class="code mark">
<span class="codemark">&nbsp;
&#9312;
&#9313;
&#9314;
&#9315;
&#9316;
&#9317;</span>local ffi = require("ffi")
ffi.cdef[[
<span style="color:#00a000;">void Sleep(int ms);
int poll(struct pollfd *fds, unsigned long nfds, int timeout);</span>
]]
local sleep
if ffi.os == "Windows" then <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9313;</span>
function sleep(s) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
ffi.C.Sleep(s*1000) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9315;</span>
if ffi.os == "Windows" then
function sleep(s)
ffi.C.Sleep(s*1000)
end
else
function sleep(s)
ffi.C.poll(nil, 0, s*1000) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9316;</span>
ffi.C.poll(nil, 0, s*1000)
end
end
for i=1,160 do
io.write("."); io.flush()
sleep(0.01) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9317;</span>
sleep(0.01)
end
io.write("\n")
</pre>
@ -122,14 +146,14 @@ io.write("\n")
Here's the step-by-step explanation:
</p>
<p>
<span style="color:#4040c0;">&#9312;</span> This defines the
<span class="mark">&#9312;</span> This defines the
C&nbsp;library functions we're going to use. The part inside the
double-brackets (in green) is just standard C&nbsp;syntax. You can
usually get this info from the C&nbsp;header files or the
documentation provided by each C&nbsp;library or C&nbsp;compiler.
</p>
<p>
<span style="color:#4040c0;">&#9313;</span> The difficulty we're
<span class="mark">&#9313;</span> The difficulty we're
facing here, is that there are different standards to choose from.
Windows has a simple <tt>Sleep()</tt> function. On other systems there
are a variety of functions available to achieve sub-second sleeps, but
@ -139,14 +163,14 @@ check for <tt>ffi.os</tt> makes sure we use the Windows-specific
function only on Windows systems.
</p>
<p>
<span style="color:#4040c0;">&#9314;</span> Here we're wrapping the
<span class="mark">&#9314;</span> Here we're wrapping the
call to the C&nbsp;function in a Lua function. This isn't strictly
necessary, but it's helpful to deal with system-specific issues only
in one part of the code. The way we're wrapping it ensures the check
for the OS is only done during initialization and not for every call.
</p>
<p>
<span style="color:#4040c0;">&#9315;</span> A more subtle point is
<span class="mark">&#9315;</span> A more subtle point is
that we defined our <tt>sleep()</tt> function (for the sake of this
example) as taking the number of seconds, but accepting fractional
seconds. Multiplying this by 1000 gets us milliseconds, but that still
@ -165,7 +189,7 @@ FFI library automatically detects <tt>stdcall</tt> functions, so you
don't need to declare them as such.
</p>
<p>
<span style="color:#4040c0;">&#9316;</span> The <tt>poll()</tt>
<span class="mark">&#9316;</span> The <tt>poll()</tt>
function takes a couple more arguments we're not going to use. You can
simply use <tt>nil</tt> to pass a <tt>NULL</tt> pointer and <tt>0</tt>
for the <tt>nfds</tt> parameter. Please note that the
@ -182,7 +206,7 @@ with this, as it's performed automatically and it's carefully designed
to bridge the semantic differences between Lua and C.
</p>
<p>
<span style="color:#4040c0;">&#9317;</span> Now that we have defined
<span class="mark">&#9317;</span> Now that we have defined
our own <tt>sleep()</tt> function, we can just call it from plain Lua
code. That wasn't so bad, huh? Turning these boring animated dots into
a fascinating best-selling game is left as an exercise for the reader.
@ -196,27 +220,54 @@ href="http://zlib.net/">zlib</a> compression library from Lua code.
We'll define two convenience wrapper functions that take a string and
compress or uncompress it to another string:
</p>
<pre class="code">
local ffi = require("ffi")
ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">&#9312;</span>
<pre class="code mark">
<span class="codemark">&nbsp;
&#9312;
&#9313;
&#9314;
&#9315;
&#9316;
&#9317;
&#9318;</span>local ffi = require("ffi")
ffi.cdef[[
<span style="color:#00a000;">unsigned long compressBound(unsigned long sourceLen);
int compress2(uint8_t *dest, unsigned long *destLen,
const uint8_t *source, unsigned long sourceLen, int level);
int uncompress(uint8_t *dest, unsigned long *destLen,
const uint8_t *source, unsigned long sourceLen);</span>
]]
local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9313;</span>
local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")
local function compress(txt)
local n = zlib.compressBound(#txt) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
local n = zlib.compressBound(#txt)
local buf = ffi.new("uint8_t[?]", n)
local buflen = ffi.new("unsigned long[1]", n) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9315;</span>
local buflen = ffi.new("unsigned long[1]", n)
local res = zlib.compress2(buf, buflen, txt, #txt, 9)
assert(res == 0)
return ffi.string(buf, buflen[0]) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9316;</span>
return ffi.string(buf, buflen[0])
end
local function uncompress(comp, n) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9317;</span>
local function uncompress(comp, n)
local buf = ffi.new("uint8_t[?]", n)
local buflen = ffi.new("unsigned long[1]", n)
local res = zlib.uncompress(buf, buflen, comp, #comp)
@ -224,7 +275,7 @@ local function uncompress(comp, n) <span style="color:#f0f4ff;">--</span><span s
return ffi.string(buf, buflen[0])
end
-- Simple test code. <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9318;</span>
-- Simple test code.
local txt = string.rep("abcd", 1000)
print("Uncompressed size: ", #txt)
local c = compress(txt)
@ -236,13 +287,13 @@ assert(txt2 == txt)
Here's the step-by-step explanation:
</p>
<p>
<span style="color:#4040c0;">&#9312;</span> This defines some of the
<span class="mark">&#9312;</span> This defines some of the
C&nbsp;functions provided by zlib. For the sake of this example, some
type indirections have been reduced and it uses the pre-defined
fixed-size integer types, while still adhering to the zlib API/ABI.
</p>
<p>
<span style="color:#4040c0;">&#9313;</span> This loads the zlib shared
<span class="mark">&#9313;</span> This loads the zlib shared
library. On POSIX systems it's named <tt>libz.so</tt> and usually
comes pre-installed. Since <tt>ffi.load()</tt> automatically adds any
missing standard prefixes/suffixes, we can simply load the
@ -253,7 +304,7 @@ you'll have to download it first from the
<tt>ffi.load()</tt>.
</p>
<p>
<span style="color:#4040c0;">&#9314;</span> First, the maximum size of
<span class="mark">&#9314;</span> First, the maximum size of
the compression buffer is obtained by calling the
<tt>zlib.compressBound</tt> function with the length of the
uncompressed string. The next line allocates a byte buffer of this
@ -262,7 +313,7 @@ variable-length array (VLA). The actual number of elements of this
array is given as the 2nd argument to <tt>ffi.new()</tt>.
</p>
<p>
<span style="color:#4040c0;">&#9315;</span> This may look strange at
<span class="mark">&#9315;</span> This may look strange at
first, but have a look at the declaration of the <tt>compress2</tt>
function from zlib: the destination length is defined as a pointer!
This is because you pass in the maximum buffer size and get back the
@ -276,7 +327,7 @@ initialized with the maximum buffer size in one step. Calling the
actual <tt>zlib.compress2</tt> function is then straightforward.
</p>
<p>
<span style="color:#4040c0;">&#9316;</span> We want to return the
<span class="mark">&#9316;</span> We want to return the
compressed data as a Lua string, so we'll use <tt>ffi.string()</tt>.
It needs a pointer to the start of the data and the actual length. The
length has been returned in the <tt>buflen</tt> array, so we'll just
@ -292,13 +343,13 @@ results in buffers instead of strings. This will reduce the overhead
for garbage collection and string interning.
</p>
<p>
<span style="color:#4040c0;">&#9317;</span> The <tt>uncompress</tt>
<span class="mark">&#9317;</span> The <tt>uncompress</tt>
functions does the exact opposite of the <tt>compress</tt> function.
The compressed data doesn't include the size of the original string,
so this needs to be passed in. Otherwise no surprises here.
</p>
<p>
<span style="color:#4040c0;">&#9318;</span> The code, that makes use
<span class="mark">&#9318;</span> The code, that makes use
of the functions we just defined, is just plain Lua code. It doesn't
need to know anything about the LuaJIT FFI &mdash; the convenience
wrapper functions completely hide it.

View File

@ -417,7 +417,7 @@ simply use whatever <tt>make install</tt> creates. There's a reason
for all of the files <em>and</em> directories it creates.
</p>
<p>
The build system uses GNU make and autodetects most settings based on
The build system uses GNU make and auto-detects most settings based on
the host you're building it on. This should work fine for native builds,
even when sandboxed. You may need to pass some of the following flags to
<em>both</em> the <tt>make</tt> and the <tt>make install</tt> command lines
@ -431,7 +431,7 @@ the <tt>-rpath</tt> of the shared library.</li>
to a shadow tree instead of the root tree of the build system.</li>
<li>Have a look at the top-level <tt>Makefile</tt> and <tt>src/Makefile</tt>
for additional variables to tweak. The following variables <em>may</em> be
overriden, but it's <em>not</em> recommended, except for special needs
overridden, but it's <em>not</em> recommended, except for special needs
like cross-builds:
<tt>BUILDMODE, CC, HOST_CC, STATIC_CC, DYNAMIC_CC, CFLAGS, HOST_CFLAGS,
TARGET_CFLAGS, LDFLAGS, HOST_LDFLAGS, TARGET_LDFLAGS, TARGET_SHLDFLAGS,

View File

@ -96,7 +96,7 @@ performance and an unmatched <b>low memory footprint</b>: less than
<p>
LuaJIT has been in continuous development since 2005. It's widely
considered to be <b>one of the fastest dynamic language
implementations</b>. It has outperfomed other dynamic languages on many
implementations</b>. It has outperformed other dynamic languages on many
cross-language benchmarks since its first release &mdash; often by a
substantial margin. In 2009 other dynamic language VMs started to catch up
with the performance of LuaJIT 1.x. Well, I couldn't let that slide. ;-)

View File

@ -182,9 +182,10 @@ handled correctly. The error may fall through an on-trace
<h2>Roadmap</h2>
<p>
Rather than stating exact release dates (I'm well known for making
spectacularly wrong guesses), this roadmap lists the general project
plan, sorted by priority, as well as ideas for the future:
Please refer to the
<a href="http://lua-users.org/lists/lua-l/2011-01/msg01238.html"><span class="ext">&raquo;</span>&nbsp;LuaJIT
Roadmap 2011</a> for the latest release plan. Here's the general
project plan for LuaJIT 2.0:
</p>
<ul>
<li>