mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
Cleanup of docs.
This commit is contained in:
parent
a5aade2fa9
commit
1f0006ac71
@ -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">»</span> 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>
|
||||
|
@ -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 functions and the use
|
||||
of C data structures from pure Lua code.
|
||||
|
||||
The FFI library allows <b>calling external C functions</b> and
|
||||
<b>using C 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 — it parses plain C declarations, which can be
|
||||
Lua/C bindings in C. No need to learn a separate binding language
|
||||
— <b>it parses plain C declarations!</b> These can be
|
||||
cut-n-pasted from C 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 library function:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local ffi = require("ffi") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">①</span>
|
||||
ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">②</span>
|
||||
<pre class="code mark">
|
||||
<span class="codemark">①
|
||||
②
|
||||
|
||||
|
||||
③</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;">③</span>
|
||||
ffi.C.printf("Hello %s!", "world")
|
||||
</pre>
|
||||
<p>
|
||||
So, let's pick that apart:
|
||||
</p>
|
||||
<p>
|
||||
<span style="color:#4040c0;">①</span> Load the FFI library.
|
||||
<span class="mark">①</span> Load the FFI library.
|
||||
</p>
|
||||
<p>
|
||||
<span style="color:#4040c0;">②</span> Add a C declaration
|
||||
<span class="mark">②</span> Add a C declaration
|
||||
for the function. The part inside the double-brackets (in green) is
|
||||
just standard C syntax.
|
||||
</p>
|
||||
<p>
|
||||
<span style="color:#4040c0;">③</span> Call the named
|
||||
<span class="mark">③</span> Call the named
|
||||
C function — 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;">①</span>
|
||||
<b>ffi.cdef[[
|
||||
<pre class="code mark">
|
||||
<span class="codemark">①
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
②
|
||||
|
||||
③
|
||||
④
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
③
|
||||
⑤</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;">②</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;">③</span>
|
||||
<b>img[i].green = i*f</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">④</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;">③</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;">⑤</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;">①</span> First, load the FFI
|
||||
<span class="mark">①</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 bit RGBA pixel.
|
||||
</p>
|
||||
<p>
|
||||
<span style="color:#4040c0;">②</span> Creating the data
|
||||
<span class="mark">②</span> Creating the data
|
||||
structure with <tt>ffi.new()</tt> is straightforward — the
|
||||
<tt>'?'</tt> is a placeholder for the number of elements of a
|
||||
variable-length array.
|
||||
</p>
|
||||
<p>
|
||||
<span style="color:#4040c0;">③</span> C arrays are
|
||||
<span class="mark">③</span> C 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;">④</span> Since <tt>ffi.new()</tt>
|
||||
<span class="mark">④</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;">⑤</span> The calls to
|
||||
<span class="mark">⑤</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
|
||||
|
@ -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 library functions
|
||||
(inlinable) replacement for the C 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 library function
|
||||
(inlinable) replacement for the C library function
|
||||
<tt>memset(dst, c, len)</tt>. Please note the different
|
||||
order of arguments!
|
||||
</p>
|
||||
|
@ -66,9 +66,9 @@ and its interaction with both Lua and C code.
|
||||
</p>
|
||||
<p>
|
||||
Given that the FFI library is designed to interface with C code
|
||||
and that declarations can be written in plain C syntax, it
|
||||
closely follows the C language semantics, wherever possible. Some
|
||||
minor concessions are needed for smoother interoperation with Lua
|
||||
and that declarations can be written in plain C syntax, <b>it
|
||||
closely follows the C 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 — thank
|
||||
you!
|
||||
developers. Please <a href="contact.html">report</a> any problems you
|
||||
may encounter or any improvements you'd like to see — thank you!
|
||||
</p>
|
||||
|
||||
<h2 id="clang">C Language Support</h2>
|
||||
@ -204,7 +203,7 @@ The following C features are <b>not</b> supported:
|
||||
default to an <tt>int</tt> type.</li>
|
||||
|
||||
<li>Old-style empty function declarations (K&R) are not allowed.
|
||||
All C functions must have a proper protype declaration. A
|
||||
All C functions must have a proper prototype declaration. A
|
||||
function declared without parameters (<tt>int foo();</tt>) is
|
||||
treated as a function taking zero arguments, like in C++.</li>
|
||||
|
||||
@ -312,7 +311,7 @@ C 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 function use
|
||||
<a href="#convert_vararg">special conversion rules</a>. This
|
||||
C 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 char *"</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.
|
||||
|
@ -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 milliseconds
|
||||
after each dot:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local ffi = require("ffi")
|
||||
ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">①</span>
|
||||
<pre class="code mark">
|
||||
<span class="codemark">
|
||||
①
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
②
|
||||
③
|
||||
④
|
||||
|
||||
|
||||
|
||||
⑤
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
⑥</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;">②</span>
|
||||
function sleep(s) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">③</span>
|
||||
ffi.C.Sleep(s*1000) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">④</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;">⑤</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;">⑥</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;">①</span> This defines the
|
||||
<span class="mark">①</span> This defines the
|
||||
C library functions we're going to use. The part inside the
|
||||
double-brackets (in green) is just standard C syntax. You can
|
||||
usually get this info from the C header files or the
|
||||
documentation provided by each C library or C compiler.
|
||||
</p>
|
||||
<p>
|
||||
<span style="color:#4040c0;">②</span> The difficulty we're
|
||||
<span class="mark">②</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;">③</span> Here we're wrapping the
|
||||
<span class="mark">③</span> Here we're wrapping the
|
||||
call to the C 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;">④</span> A more subtle point is
|
||||
<span class="mark">④</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;">⑤</span> The <tt>poll()</tt>
|
||||
<span class="mark">⑤</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;">⑥</span> Now that we have defined
|
||||
<span class="mark">⑥</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;">①</span>
|
||||
<pre class="code mark">
|
||||
<span class="codemark">
|
||||
①
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
②
|
||||
|
||||
|
||||
③
|
||||
|
||||
④
|
||||
|
||||
|
||||
⑤
|
||||
|
||||
|
||||
⑥
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
⑦</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;">②</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;">③</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;">④</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;">⑤</span>
|
||||
return ffi.string(buf, buflen[0])
|
||||
end
|
||||
|
||||
local function uncompress(comp, n) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">⑥</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;">⑦</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;">①</span> This defines some of the
|
||||
<span class="mark">①</span> This defines some of the
|
||||
C 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;">②</span> This loads the zlib shared
|
||||
<span class="mark">②</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;">③</span> First, the maximum size of
|
||||
<span class="mark">③</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;">④</span> This may look strange at
|
||||
<span class="mark">④</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;">⑤</span> We want to return the
|
||||
<span class="mark">⑤</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;">⑥</span> The <tt>uncompress</tt>
|
||||
<span class="mark">⑥</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;">⑦</span> The code, that makes use
|
||||
<span class="mark">⑦</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 — the convenience
|
||||
wrapper functions completely hide it.
|
||||
|
@ -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,
|
||||
|
@ -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 — 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. ;-)
|
||||
|
@ -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">»</span> LuaJIT
|
||||
Roadmap 2011</a> for the latest release plan. Here's the general
|
||||
project plan for LuaJIT 2.0:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
|
Loading…
Reference in New Issue
Block a user