summaryrefslogtreecommitdiff
path: root/libs/luajit-cmake/luajit/doc/ext_ffi.html
diff options
context:
space:
mode:
Diffstat (limited to 'libs/luajit-cmake/luajit/doc/ext_ffi.html')
-rw-r--r--libs/luajit-cmake/luajit/doc/ext_ffi.html326
1 files changed, 326 insertions, 0 deletions
diff --git a/libs/luajit-cmake/luajit/doc/ext_ffi.html b/libs/luajit-cmake/luajit/doc/ext_ffi.html
new file mode 100644
index 0000000..5f1e2d7
--- /dev/null
+++ b/libs/luajit-cmake/luajit/doc/ext_ffi.html
@@ -0,0 +1,326 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>FFI Library</title>
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2022">
+<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="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+</div>
+<div id="head">
+<h1>FFI Library</h1>
+</div>
+<div id="nav">
+<ul><li>
+<a href="luajit.html">LuaJIT</a>
+<ul><li>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+</li><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 class="current" 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_semantics.html">FFI Semantics</a>
+</li></ul>
+</li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
+<a href="ext_jit.html">jit.* Library</a>
+</li><li>
+<a href="ext_c_api.html">Lua/C API</a>
+</li><li>
+<a href="ext_profiler.html">Profiler</a>
+</li></ul>
+</li><li>
+<a href="status.html">Status</a>
+</li><li>
+<a href="faq.html">FAQ</a>
+</li><li>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+</li></ul>
+</div>
+<div id="main">
+<p>
+
+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. 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
+as a separate module). The code generated by the JIT-compiler for
+accesses to C&nbsp;data structures from Lua code is on par with the
+code a C&nbsp;compiler would generate. Calls to C&nbsp;functions can
+be inlined in JIT-compiled code, unlike calls to functions bound via
+the classic Lua/C API.
+</p>
+<p>
+This page gives a short introduction to the usage of the FFI library.
+<em>Please use the FFI sub-topics in the navigation bar to learn more.</em>
+</p>
+
+<h2 id="call">Motivating Example: Calling External C Functions</h2>
+<p>
+It's really easy to call an external C&nbsp;library function:
+</p>
+<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")
+</pre>
+<p>
+So, let's pick that apart:
+</p>
+<p>
+<span class="mark">&#9312;</span> Load the FFI library.
+</p>
+<p>
+<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 class="mark">&#9314;</span> Call the named
+C&nbsp;function &mdash; Yes, it's that simple!
+</p>
+<p style="font-size: 8pt;">
+Actually, what goes on behind the scenes is far from simple: <span
+style="color:#4040c0;">&#9314;</span> makes use of the standard
+C&nbsp;library namespace <tt>ffi.C</tt>. Indexing this namespace with
+a symbol name (<tt>"printf"</tt>) automatically binds it to the
+standard C&nbsp;library. The result is a special kind of object which,
+when called, runs the <tt>printf</tt> function. The arguments passed
+to this function are automatically converted from Lua objects to the
+corresponding C&nbsp;types.
+</p>
+<p>
+Ok, so maybe the use of <tt>printf()</tt> wasn't such a spectacular
+example. You could have done that with <tt>io.write()</tt> and
+<tt>string.format()</tt>, too. But you get the idea ...
+</p>
+<p>
+So here's something to pop up a message box on Windows:
+</p>
+<pre class="code">
+local ffi = require("ffi")
+ffi.cdef[[
+<span style="color:#00a000;">int MessageBoxA(void *w, const char *txt, const char *cap, int type);</span>
+]]
+ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0)
+</pre>
+<p>
+Bing! Again, that was far too easy, no?
+</p>
+<p style="font-size: 8pt;">
+Compare this with the effort required to bind that function using the
+classic Lua/C API: create an extra C&nbsp;file, add a C&nbsp;function
+that retrieves and checks the argument types passed from Lua and calls
+the actual C&nbsp;function, add a list of module functions and their
+names, add a <tt>luaopen_*</tt> function and register all module
+functions, compile and link it into a shared library (DLL), move it to
+the proper path, add Lua code that loads the module aaaand ... finally
+call the binding function. Phew!
+</p>
+
+<h2 id="cdata">Motivating Example: Using C Data Structures</h2>
+<p>
+The FFI library allows you to create and access C&nbsp;data
+structures. Of course, the main use for this is for interfacing with
+C&nbsp;functions. But they can be used stand-alone, too.
+</p>
+<p>
+Lua is built upon high-level data types. They are flexible, extensible
+and dynamic. That's why we all love Lua so much. Alas, this can be
+inefficient for certain tasks, where you'd really want a low-level
+data type. E.g. a large array of a fixed structure needs to be
+implemented with a big table holding lots of tiny tables. This imposes
+both a substantial memory overhead as well as a performance overhead.
+</p>
+<p>
+Here's a sketch of a library that operates on color images, plus a
+simple benchmark. First, the plain Lua version:
+</p>
+<pre class="code">
+local floor = math.floor
+
+local function image_ramp_green(n)
+ local img = {}
+ local f = 255/(n-1)
+ for i=1,n do
+ img[i] = { red = 0, green = floor((i-1)*f), blue = 0, alpha = 255 }
+ end
+ return img
+end
+
+local function image_to_gray(img, n)
+ for i=1,n do
+ local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)
+ img[i].red = y; img[i].green = y; img[i].blue = y
+ end
+end
+
+local N = 400*400
+local img = image_ramp_green(N)
+for i=1,1000 do
+ image_to_gray(img, N)
+end
+</pre>
+<p>
+This creates a table with 160.000 pixels, each of which is a table
+holding four number values in the range of 0-255. First, an image with
+a green ramp is created (1D for simplicity), then the image is
+converted to grayscale 1000 times. Yes, that's silly, but I was in
+need of a simple example ...
+</p>
+<p>
+And here's the FFI version. The modified parts have been marked in
+bold:
+</p>
+<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>
+ local f = 255/(n-1)
+ 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
+ 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
+
+local N = 400*400
+local img = image_ramp_green(N)
+for i=1,1000 do
+ image_to_grey(img, N)
+end
+</pre>
+<p>
+Ok, so that wasn't too difficult:
+</p>
+<p>
+<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 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 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 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 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
+fields of each pixel.
+</p>
+<p>
+Now let's have a look at the impact of the changes: first, memory
+consumption for the image is down from 22&nbsp;Megabytes to
+640&nbsp;Kilobytes (400*400*4 bytes). That's a factor of 35x less! So,
+yes, tables do have a noticeable overhead. BTW: The original program
+would consume 40&nbsp;Megabytes in plain Lua (on x64).
+</p>
+<p>
+Next, performance: the pure Lua version runs in 9.57 seconds (52.9
+seconds with the Lua interpreter) and the FFI version runs in 0.48
+seconds on my machine (YMMV). That's a factor of 20x faster (110x
+faster than the Lua interpreter).
+</p>
+<p style="font-size: 8pt;">
+The avid reader may notice that converting the pure Lua version over
+to use array indexes for the colors (<tt>[1]</tt> instead of
+<tt>.red</tt>, <tt>[2]</tt> instead of <tt>.green</tt> etc.) ought to
+be more compact and faster. This is certainly true (by a factor of
+~1.7x). Switching to a struct-of-arrays would help, too.
+</p>
+<p style="font-size: 8pt;">
+However, the resulting code would be less idiomatic and rather
+error-prone. And it still doesn't get even close to the performance of
+the FFI version of the code. Also, high-level data structures cannot
+be easily passed to other C&nbsp;functions, especially I/O functions,
+without undue conversion penalties.
+</p>
+<br class="flush">
+</div>
+<div id="foot">
+<hr class="hide">
+Copyright &copy; 2005-2022
+<span class="noprint">
+&middot;
+<a href="contact.html">Contact</a>
+</span>
+</div>
+</body>
+</html>