aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMike Pall <mike>2011-02-11 01:21:46 +0100
committerMike Pall <mike>2011-02-11 01:21:46 +0100
commita5aade2fa9ff89f9f3c4a91261071299de0d0fa4 (patch)
treed253cfe022944c9754ebe43810a73c141130f058 /doc
parenta2f9f1f831c77b19433b9f8858b9c1db0e421800 (diff)
downloadluajit-a5aade2fa9ff89f9f3c4a91261071299de0d0fa4.tar.gz
luajit-a5aade2fa9ff89f9f3c4a91261071299de0d0fa4.tar.bz2
luajit-a5aade2fa9ff89f9f3c4a91261071299de0d0fa4.zip
FFI: Finish FFI docs.
Diffstat (limited to 'doc')
-rw-r--r--doc/changes.html2
-rw-r--r--doc/contact.html2
-rw-r--r--doc/ext_c_api.html2
-rw-r--r--doc/ext_ffi.html92
-rw-r--r--doc/ext_ffi_api.html49
-rw-r--r--doc/ext_ffi_int64.html73
-rw-r--r--doc/ext_ffi_semantics.html40
-rw-r--r--doc/ext_ffi_tutorial.html352
-rw-r--r--doc/ext_jit.html2
-rw-r--r--doc/extensions.html2
-rw-r--r--doc/faq.html2
-rw-r--r--doc/install.html2
-rw-r--r--doc/luajit.html2
-rw-r--r--doc/running.html2
-rw-r--r--doc/status.html2
15 files changed, 469 insertions, 157 deletions
diff --git a/doc/changes.html b/doc/changes.html
index 2107193a..04e26e40 100644
--- a/doc/changes.html
+++ b/doc/changes.html
@@ -36,8 +36,6 @@ div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
36</li><li> 36</li><li>
37<a href="ext_ffi_api.html">ffi.* API</a> 37<a href="ext_ffi_api.html">ffi.* API</a>
38</li><li> 38</li><li>
39<a href="ext_ffi_int64.html">64 bit Integers</a>
40</li><li>
41<a href="ext_ffi_semantics.html">FFI Semantics</a> 39<a href="ext_ffi_semantics.html">FFI Semantics</a>
42</li></ul> 40</li></ul>
43</li><li> 41</li><li>
diff --git a/doc/contact.html b/doc/contact.html
index a979cb2f..a85c4884 100644
--- a/doc/contact.html
+++ b/doc/contact.html
@@ -33,8 +33,6 @@
33</li><li> 33</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a> 34<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li> 35</li><li>
36<a href="ext_ffi_int64.html">64 bit Integers</a>
37</li><li>
38<a href="ext_ffi_semantics.html">FFI Semantics</a> 36<a href="ext_ffi_semantics.html">FFI Semantics</a>
39</li></ul> 37</li></ul>
40</li><li> 38</li><li>
diff --git a/doc/ext_c_api.html b/doc/ext_c_api.html
index 119c89f5..35e2234e 100644
--- a/doc/ext_c_api.html
+++ b/doc/ext_c_api.html
@@ -33,8 +33,6 @@
33</li><li> 33</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a> 34<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li> 35</li><li>
36<a href="ext_ffi_int64.html">64 bit Integers</a>
37</li><li>
38<a href="ext_ffi_semantics.html">FFI Semantics</a> 36<a href="ext_ffi_semantics.html">FFI Semantics</a>
39</li></ul> 37</li></ul>
40</li><li> 38</li><li>
diff --git a/doc/ext_ffi.html b/doc/ext_ffi.html
index 50a44052..1fd276dc 100644
--- a/doc/ext_ffi.html
+++ b/doc/ext_ffi.html
@@ -33,8 +33,6 @@
33</li><li> 33</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a> 34<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li> 35</li><li>
36<a href="ext_ffi_int64.html">64 bit Integers</a>
37</li><li>
38<a href="ext_ffi_semantics.html">FFI Semantics</a> 36<a href="ext_ffi_semantics.html">FFI Semantics</a>
39</li></ul> 37</li></ul>
40</li><li> 38</li><li>
@@ -86,22 +84,30 @@ Please use the FFI sub-topics in the navigation bar to learn more.
86It's really easy to call an external C&nbsp;library function: 84It's really easy to call an external C&nbsp;library function:
87</p> 85</p>
88<pre class="code"> 86<pre class="code">
89<span style="color:#000080;">local ffi = require("ffi")</span> 87local ffi = require("ffi") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9312;</span>
90ffi.cdef[[ 88ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">&#9313;</span>
91<span style="color:#00a000;font-weight:bold;">int printf(const char *fmt, ...);</span> 89<span style="color:#00a000;">int printf(const char *fmt, ...);</span>
92]] 90]]
93<span style="color:#c06000;font-weight:bold;">ffi.C</span>.printf("Hello %s!", "world") 91ffi.C.printf("Hello %s!", "world") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
94</pre> 92</pre>
95<p> 93<p>
96So, let's pick that apart: the first line (in blue) loads the FFI 94So, let's pick that apart:
97library. The next one adds a C&nbsp;declaration for the function. The 95</p>
98part between the double-brackets (in green) is just standard 96<p>
99C&nbsp;syntax. And the last line calls the named C&nbsp;function. Yes, 97<span style="color:#4040c0;">&#9312;</span> Load the FFI library.
100it's that simple! 98</p>
99<p>
100<span style="color:#4040c0;">&#9313;</span> Add a C&nbsp;declaration
101for the function. The part inside the double-brackets (in green) is
102just standard C&nbsp;syntax.
103</p>
104<p>
105<span style="color:#4040c0;">&#9314;</span> Call the named
106C&nbsp;function &mdash; Yes, it's that simple!
101</p> 107</p>
102<p style="font-size: 8pt;"> 108<p style="font-size: 8pt;">
103Actually, what goes on behind the scenes is far from simple: the first 109Actually, what goes on behind the scenes is far from simple: <span
104part of the last line (in orange) makes use of the standard 110style="color:#4040c0;">&#9314;</span> makes use of the standard
105C&nbsp;library namespace <tt>ffi.C</tt>. Indexing this namespace with 111C&nbsp;library namespace <tt>ffi.C</tt>. Indexing this namespace with
106a symbol name (<tt>"printf"</tt>) automatically binds it to the the 112a symbol name (<tt>"printf"</tt>) automatically binds it to the the
107standard C&nbsp;library. The result is a special kind of object which, 113standard C&nbsp;library. The result is a special kind of object which,
@@ -120,7 +126,7 @@ So here's something to pop up a message box on Windows:
120<pre class="code"> 126<pre class="code">
121local ffi = require("ffi") 127local ffi = require("ffi")
122ffi.cdef[[ 128ffi.cdef[[
123int MessageBoxA(void *w, const char *txt, const char *cap, int type); 129<span style="color:#00a000;">int MessageBoxA(void *w, const char *txt, const char *cap, int type);</span>
124]] 130]]
125ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0) 131ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0)
126</pre> 132</pre>
@@ -193,24 +199,24 @@ And here's the FFI version. The modified parts have been marked in
193bold: 199bold:
194</p> 200</p>
195<pre class="code"> 201<pre class="code">
196<b>local ffi = require("ffi") 202<b>local ffi = require("ffi")</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9312;</span>
197ffi.cdef[[ 203<b>ffi.cdef[[
198typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel; 204</b><span style="color:#00a000;">typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;</span><b>
199]]</b> 205]]</b>
200 206
201local function image_ramp_green(n) 207local function image_ramp_green(n)
202 <b>local img = ffi.new("rgba_pixel[?]", n)</b> 208 <b>local img = ffi.new("rgba_pixel[?]", n)</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9313;</span>
203 local f = 255/(n-1) 209 local f = 255/(n-1)
204 for i=<b>0,n-1</b> do 210 for i=<b>0,n-1</b> do <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
205 <b>img[i].green = i*f</b> 211 <b>img[i].green = i*f</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9315;</span>
206 <b>img[i].alpha = 255</b> 212 <b>img[i].alpha = 255</b>
207 end 213 end
208 return img 214 return img
209end 215end
210 216
211local function image_to_grey(img, n) 217local function image_to_grey(img, n)
212 for i=<b>0,n-1</b> do 218 for i=<b>0,n-1</b> do <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
213 local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b> 219 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>
214 img[i].red = y; img[i].green = y; img[i].blue = y 220 img[i].red = y; img[i].green = y; img[i].blue = y
215 end 221 end
216end 222end
@@ -222,25 +228,37 @@ for i=1,1000 do
222end 228end
223</pre> 229</pre>
224<p> 230<p>
225Ok, so that wasn't too difficult: first, load the FFI library and 231Ok, so that wasn't too difficult:
226declare the low-level data type. Here we choose a <tt>struct</tt> 232</p>
227which holds four byte fields, one for each component of a 4x8&nbsp;bit 233<p>
228RGBA pixel. 234<span style="color:#4040c0;">&#9312;</span> First, load the FFI
235library and declare the low-level data type. Here we choose a
236<tt>struct</tt> which holds four byte fields, one for each component
237of a 4x8&nbsp;bit RGBA pixel.
238</p>
239<p>
240<span style="color:#4040c0;">&#9313;</span> Creating the data
241structure with <tt>ffi.new()</tt> is straightforward &mdash; the
242<tt>'?'</tt> is a placeholder for the number of elements of a
243variable-length array.
244</p>
245<p>
246<span style="color:#4040c0;">&#9314;</span> C&nbsp;arrays are
247zero-based, so the indexes have to run from <tt>0</tt> to
248<tt>n-1</tt>. One might want to allocate one more element instead to
249simplify converting legacy code.
229</p> 250</p>
230<p> 251<p>
231Creating the data structure with <tt>ffi.new()</tt> is straightforward 252<span style="color:#4040c0;">&#9315;</span> Since <tt>ffi.new()</tt>
232&mdash; the <tt>'?'</tt> is a placeholder for the number of elements 253zero-fills the array by default, we only need to set the green and the
233of a variable-length array. C&nbsp;arrays are zero-based, so the 254alpha fields.
234indexes have to run from <tt>0</tt> to <tt>n-1</tt> (one might
235allocate one more element instead to simplify converting legacy
236code). Since <tt>ffi.new()</tt> zero-fills the array by default, we
237only need to set the green and the alpha fields.
238</p> 255</p>
239<p> 256<p>
240The calls to <tt>math.floor()</tt> can be omitted here, because 257<span style="color:#4040c0;">&#9316;</span> The calls to
241floating-point numbers are already truncated towards zero when 258<tt>math.floor()</tt> can be omitted here, because floating-point
242converting them to an integer. This happens implicitly when the number 259numbers are already truncated towards zero when converting them to an
243is stored in the fields of each pixel. 260integer. This happens implicitly when the number is stored in the
261fields of each pixel.
244</p> 262</p>
245<p> 263<p>
246Now let's have a look at the impact of the changes: first, memory 264Now let's have a look at the impact of the changes: first, memory
diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html
index 7c2e53dd..9bedd52e 100644
--- a/doc/ext_ffi_api.html
+++ b/doc/ext_ffi_api.html
@@ -38,8 +38,6 @@ td.abiparam { font-weight: bold; width: 6em; }
38</li><li> 38</li><li>
39<a class="current" href="ext_ffi_api.html">ffi.* API</a> 39<a class="current" href="ext_ffi_api.html">ffi.* API</a>
40</li><li> 40</li><li>
41<a href="ext_ffi_int64.html">64 bit Integers</a>
42</li><li>
43<a href="ext_ffi_semantics.html">FFI Semantics</a> 41<a href="ext_ffi_semantics.html">FFI Semantics</a>
44</li></ul> 42</li></ul>
45</li><li> 43</li><li>
@@ -106,7 +104,7 @@ follows:
106</p> 104</p>
107<pre class="code"> 105<pre class="code">
108ffi.cdef[[ 106ffi.cdef[[
109<span style="color:#00a000;font-weight:bold;">typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef. 107<span style="color:#00a000;">typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
110int dofoo(foo_t *f, int n); /* Declare an external C function. */</span> 108int dofoo(foo_t *f, int n); /* Declare an external C function. */</span>
111]] 109]]
112</pre> 110</pre>
@@ -237,12 +235,8 @@ rules</a>.
237</p> 235</p>
238<p> 236<p>
239This functions is mainly useful to override the pointer compatibility 237This functions is mainly useful to override the pointer compatibility
240rules or to convert pointers to addresses or vice versa. For maximum 238checks or to convert pointers to addresses or vice versa.
241portability you should convert a pointer to its address as follows:
242</p> 239</p>
243<pre class="code">
244local addr = tonumber(ffi.cast("intptr_t", ptr))
245</pre>
246 240
247<h2 id="info">C&nbsp;Type Information</h2> 241<h2 id="info">C&nbsp;Type Information</h2>
248<p> 242<p>
@@ -383,6 +377,45 @@ Contains the target OS name. Same contents as
383Contains the target architecture name. Same contents as 377Contains the target architecture name. Same contents as
384<a href="ext_jit.html#jit_arch"><tt>jit.arch</tt></a>. 378<a href="ext_jit.html#jit_arch"><tt>jit.arch</tt></a>.
385</p> 379</p>
380
381<h2 id="extended">Extended Standard Library Functions</h2>
382<p>
383The following standard library functions have been extended to work
384with cdata objects:
385</p>
386
387<h3 id="tonumber"><tt>n = tonumber(cdata)</tt></h3>
388<p>
389Converts a number cdata object to a <tt>double</tt> and returns it as
390a Lua number. This is particularly useful for boxed 64&nbsp;bit
391integer values. Caveat: this conversion may incur a precision loss.
392</p>
393
394<h3 id="tostring"><tt>s = tostring(cdata)</tt></h3>
395<p>
396Returns a string representation of the value of 64&nbsp;bit integers
397(<tt><b>"</b>nnn<b>LL"</b></tt> or <tt><b>"</b>nnn<b>ULL"</b></tt>) or
398complex numbers (<tt><b>"</b>re&plusmn;im<b>i"</b></tt>). Otherwise
399returns a string representation of the C&nbsp;type of a ctype object
400(<tt><b>"ctype&lt;</b>type<b>&gt;"</b></tt>) or a cdata object
401(<tt><b>"cdata&lt;</b>type<b>&gt;:&nbsp;</b>address"</tt>).
402</p>
403
404<h2 id="literals">Extensions to the Lua Parser</h2>
405<p>
406The parser for Lua source code treats numeric literals with the
407suffixes <tt>LL</tt> or <tt>ULL</tt> as signed or unsigned 64&nbsp;bit
408integers. Case doesn't matter, but uppercase is recommended for
409readability. It handles both decimal (<tt>42LL</tt>) and hexadecimal
410(<tt>0x2aLL</tt>) literals.
411</p>
412<p>
413The imaginary part of complex numbers can be specified by suffixing
414number literals with <tt>i</tt> or <tt>I</tt>, e.g. <tt>12.5i</tt>.
415Caveat: you'll need to use <tt>1i</tt> to get an imaginary part with
416the value one, since <tt>i</tt> itself still refers to a variable
417named <tt>i</tt>.
418</p>
386<br class="flush"> 419<br class="flush">
387</div> 420</div>
388<div id="foot"> 421<div id="foot">
diff --git a/doc/ext_ffi_int64.html b/doc/ext_ffi_int64.html
deleted file mode 100644
index fa155825..00000000
--- a/doc/ext_ffi_int64.html
+++ /dev/null
@@ -1,73 +0,0 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>64 bit Integers</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>64 bit Integers</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="luajit.html">LuaJIT</a>
22<ul><li>
23<a href="install.html">Installation</a>
24</li><li>
25<a href="running.html">Running</a>
26</li></ul>
27</li><li>
28<a href="extensions.html">Extensions</a>
29<ul><li>
30<a href="ext_ffi.html">FFI Library</a>
31<ul><li>
32<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
33</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li>
36<a class="current" href="ext_ffi_int64.html">64 bit Integers</a>
37</li><li>
38<a href="ext_ffi_semantics.html">FFI Semantics</a>
39</li></ul>
40</li><li>
41<a href="ext_jit.html">jit.* Library</a>
42</li><li>
43<a href="ext_c_api.html">Lua/C API</a>
44</li></ul>
45</li><li>
46<a href="status.html">Status</a>
47<ul><li>
48<a href="changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="faq.html">FAQ</a>
52</li><li>
53<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
54</li><li>
55<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
56</li></ul>
57</div>
58<div id="main">
59<p>
60TODO
61</p>
62<br class="flush">
63</div>
64<div id="foot">
65<hr class="hide">
66Copyright &copy; 2005-2011 Mike Pall
67<span class="noprint">
68&middot;
69<a href="contact.html">Contact</a>
70</span>
71</div>
72</body>
73</html>
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html
index b2b3af30..69dfc2ca 100644
--- a/doc/ext_ffi_semantics.html
+++ b/doc/ext_ffi_semantics.html
@@ -39,8 +39,6 @@ td.convop { font-style: italic; width: 16em; }
39</li><li> 39</li><li>
40<a href="ext_ffi_api.html">ffi.* API</a> 40<a href="ext_ffi_api.html">ffi.* API</a>
41</li><li> 41</li><li>
42<a href="ext_ffi_int64.html">64 bit Integers</a>
43</li><li>
44<a class="current" href="ext_ffi_semantics.html">FFI Semantics</a> 42<a class="current" href="ext_ffi_semantics.html">FFI Semantics</a>
45</li></ul> 43</li></ul>
46</li><li> 44</li><li>
@@ -653,7 +651,10 @@ parameters given by the function declaration. Arguments passed to the
653variable argument part of vararg C&nbsp;function use 651variable argument part of vararg C&nbsp;function use
654<a href="#convert_vararg">special conversion rules</a>. This 652<a href="#convert_vararg">special conversion rules</a>. This
655C&nbsp;function is called and the return value (if any) is 653C&nbsp;function is called and the return value (if any) is
656<a href="#convert_tolua">converted to a Lua object</a>.</li> 654<a href="#convert_tolua">converted to a Lua object</a>.<br>
655On Windows/x86 systems, <tt>stdcall</tt> functions are automatically
656detected and a function declared as <tt>cdecl</tt> (the default) is
657silently fixed up after the first call.</li>
657 658
658</ul> 659</ul>
659 660
@@ -672,15 +673,24 @@ can be subtracted. The result is the difference between their
672addresses, divided by the element size in bytes. An error is raised if 673addresses, divided by the element size in bytes. An error is raised if
673the element size is undefined or zero.</li> 674the element size is undefined or zero.</li>
674 675
675<li><a href="ext_ffi_int64.html">64&nbsp;bit integer arithmetic</a>: 676<li><b>64&nbsp;bit integer arithmetic</b>: the standard arithmetic
676the standard arithmetic operators 677operators (<tt>+&nbsp;-&nbsp;*&nbsp;/&nbsp;%&nbsp;^</tt> and unary
677(<tt>+&nbsp;-&nbsp;*&nbsp;/&nbsp;%&nbsp;^</tt> and unary <tt>-</tt>) 678minus) can be applied to two cdata numbers, or a cdata number and a
678can be applied to two cdata numbers, or a cdata number and a Lua 679Lua number. If one of them is an <tt>uint64_t</tt>, the other side is
679number. If one of them is an <tt>uint64_t</tt>, the other side is
680converted to an <tt>uint64_t</tt> and an unsigned arithmetic operation 680converted to an <tt>uint64_t</tt> and an unsigned arithmetic operation
681is performed. Otherwise both sides are converted to an 681is performed. Otherwise both sides are converted to an
682<tt>int64_t</tt> and a signed arithmetic operation is performed. The 682<tt>int64_t</tt> and a signed arithmetic operation is performed. The
683result is a boxed 64&nbsp;bit cdata object.</li> 683result is a boxed 64&nbsp;bit cdata object.<br>
684
685These rules ensure that 64&nbsp;bit integers are "sticky". Any
686expression involving at least one 64&nbsp;bit integer operand results
687in another one. The undefined cases for the division, modulo and power
688operators return <tt>2LL&nbsp;^&nbsp;63</tt> or
689<tt>2ULL&nbsp;^&nbsp;63</tt>.<br>
690
691You'll have to explicitly convert a 64&nbsp;bit integer to a Lua
692number (e.g. for regular floating-point calculations) with
693<tt>tonumber()</tt>. But note this may incur a precision loss.</li>
684 694
685</ul> 695</ul>
686 696
@@ -692,12 +702,12 @@ can be compared. The result is the same as an unsigned comparison of
692their addresses. <tt>nil</tt> is treated like a <tt>NULL</tt> pointer, 702their addresses. <tt>nil</tt> is treated like a <tt>NULL</tt> pointer,
693which is compatible with any other pointer type.</li> 703which is compatible with any other pointer type.</li>
694 704
695<li><a href="ext_ffi_int64.html">64&nbsp;bit integer comparison</a>: 705<li><b>64&nbsp;bit integer comparison</b>: two cdata numbers, or a
696two cdata numbers, or a cdata number and a Lua number can be compared 706cdata number and a Lua number can be compared with each other. If one
697with each other. If one of them is an <tt>uint64_t</tt>, the other 707of them is an <tt>uint64_t</tt>, the other side is converted to an
698side is converted to an <tt>uint64_t</tt> and an unsigned comparison 708<tt>uint64_t</tt> and an unsigned comparison is performed. Otherwise
699is performed. Otherwise both sides are converted to an 709both sides are converted to an <tt>int64_t</tt> and a signed
700<tt>int64_t</tt> and a signed comparison is performed.</li> 710comparison is performed.</li>
701 711
702</ul> 712</ul>
703 713
diff --git a/doc/ext_ffi_tutorial.html b/doc/ext_ffi_tutorial.html
index 11e83339..c43b223b 100644
--- a/doc/ext_ffi_tutorial.html
+++ b/doc/ext_ffi_tutorial.html
@@ -8,6 +8,13 @@
8<meta name="Language" content="en"> 8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> 9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> 10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.idiomtable { line-height: 1.2; }
13tr.idiomhead td { font-weight: bold; }
14td.idiomc { width: 12em; }
15td.idiomlua { width: 14em; }
16td.idiomlua b { font-weight: normal; color: #2142bf; }
17</style>
11</head> 18</head>
12<body> 19<body>
13<div id="site"> 20<div id="site">
@@ -33,8 +40,6 @@
33</li><li> 40</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a> 41<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li> 42</li><li>
36<a href="ext_ffi_int64.html">64 bit Integers</a>
37</li><li>
38<a href="ext_ffi_semantics.html">FFI Semantics</a> 43<a href="ext_ffi_semantics.html">FFI Semantics</a>
39</li></ul> 44</li></ul>
40</li><li> 45</li><li>
@@ -57,7 +62,14 @@
57</div> 62</div>
58<div id="main"> 63<div id="main">
59<p> 64<p>
60TODO 65This page is intended to give you an overview of the features of the FFI
66library by presenting a few use cases and guidelines.
67</p>
68<p>
69This page makes no attempt to explain all of the FFI library, though.
70You'll want to have a look at the <a href="ext_ffi_api.html">ffi.* API
71function reference</a> and the <a href="ext_ffi_semantics.html">FFI
72semantics</a> to learn more.
61</p> 73</p>
62 74
63<h2 id="load">Loading the FFI Library</h2> 75<h2 id="load">Loading the FFI Library</h2>
@@ -76,7 +88,339 @@ of globals &mdash; you really need to use the local variable. The
76<tt>require</tt> function ensures the library is only loaded once. 88<tt>require</tt> function ensures the library is only loaded once.
77</p> 89</p>
78 90
79<h2>TODO</h2> 91<h2 id="sleep">Accessing Standard System Functions</h2>
92<p>
93The following code explains how to access standard system functions.
94We slowly print two lines of dots by sleeping for 10&nbsp;milliseconds
95after each dot:
96</p>
97<pre class="code">
98local ffi = require("ffi")
99ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">&#9312;</span>
100<span style="color:#00a000;">void Sleep(int ms);
101int poll(struct pollfd *fds, unsigned long nfds, int timeout);</span>
102]]
103
104local sleep
105if ffi.os == "Windows" then <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9313;</span>
106 function sleep(s) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
107 ffi.C.Sleep(s*1000) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9315;</span>
108 end
109else
110 function sleep(s)
111 ffi.C.poll(nil, 0, s*1000) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9316;</span>
112 end
113end
114
115for i=1,160 do
116 io.write("."); io.flush()
117 sleep(0.01) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9317;</span>
118end
119io.write("\n")
120</pre>
121<p>
122Here's the step-by-step explanation:
123</p>
124<p>
125<span style="color:#4040c0;">&#9312;</span> This defines the
126C&nbsp;library functions we're going to use. The part inside the
127double-brackets (in green) is just standard C&nbsp;syntax. You can
128usually get this info from the C&nbsp;header files or the
129documentation provided by each C&nbsp;library or C&nbsp;compiler.
130</p>
131<p>
132<span style="color:#4040c0;">&#9313;</span> The difficulty we're
133facing here, is that there are different standards to choose from.
134Windows has a simple <tt>Sleep()</tt> function. On other systems there
135are a variety of functions available to achieve sub-second sleeps, but
136with no clear consensus. Thankfully <tt>poll()</tt> can be used for
137this task, too, and it's present on most non-Windows systems. The
138check for <tt>ffi.os</tt> makes sure we use the Windows-specific
139function only on Windows systems.
140</p>
141<p>
142<span style="color:#4040c0;">&#9314;</span> Here we're wrapping the
143call to the C&nbsp;function in a Lua function. This isn't strictly
144necessary, but it's helpful to deal with system-specific issues only
145in one part of the code. The way we're wrapping it ensures the check
146for the OS is only done during initialization and not for every call.
147</p>
148<p>
149<span style="color:#4040c0;">&#9315;</span> A more subtle point is
150that we defined our <tt>sleep()</tt> function (for the sake of this
151example) as taking the number of seconds, but accepting fractional
152seconds. Multiplying this by 1000 gets us milliseconds, but that still
153leaves it a Lua number, which is a floating-point value. Alas, the
154<tt>Sleep()</tt> function only accepts an integer value. Luckily for
155us, the FFI library automatically performs the conversion when calling
156the function (truncating the FP value towards zero, like in C).
157</p>
158<p style="font-size: 8pt;">
159Some readers will notice that <tt>Sleep()</tt> is part of
160<tt>KERNEL32.DLL</tt> and is also a <tt>stdcall</tt> function. So how
161can this possibly work? The FFI library provides the <tt>ffi.C</tt>
162default C&nbsp;library namespace, which allows calling functions from
163the default set of libraries, like a C&nbsp;compiler would. Also, the
164FFI library automatically detects <tt>stdcall</tt> functions, so you
165don't need to declare them as such.
166</p>
167<p>
168<span style="color:#4040c0;">&#9316;</span> The <tt>poll()</tt>
169function takes a couple more arguments we're not going to use. You can
170simply use <tt>nil</tt> to pass a <tt>NULL</tt> pointer and <tt>0</tt>
171for the <tt>nfds</tt> parameter. Please note that the
172number&nbsp;<tt>0</tt> <em>does not convert to a pointer value</em>,
173unlike in C++. You really have to pass pointers to pointer arguments
174and numbers to number arguments.
175</p>
176<p style="font-size: 8pt;">
177The page on <a href="ext_ffi_semantics.html">FFI semantics</a> has all
178of the gory details about
179<a href="ext_ffi_semantics.html#convert">conversions between Lua
180objects and C&nbsp;types</a>. For the most part you don't have to deal
181with this, as it's performed automatically and it's carefully designed
182to bridge the semantic differences between Lua and C.
183</p>
184<p>
185<span style="color:#4040c0;">&#9317;</span> Now that we have defined
186our own <tt>sleep()</tt> function, we can just call it from plain Lua
187code. That wasn't so bad, huh? Turning these boring animated dots into
188a fascinating best-selling game is left as an exercise for the reader.
189:-)
190</p>
191
192<h2 id="zlib">Accessing the zlib Compression Library</h2>
193<p>
194The following code shows how to access the <a
195href="http://zlib.net/">zlib</a> compression library from Lua code.
196We'll define two convenience wrapper functions that take a string and
197compress or uncompress it to another string:
198</p>
199<pre class="code">
200local ffi = require("ffi")
201ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">&#9312;</span>
202<span style="color:#00a000;">unsigned long compressBound(unsigned long sourceLen);
203int compress2(uint8_t *dest, unsigned long *destLen,
204 const uint8_t *source, unsigned long sourceLen, int level);
205int uncompress(uint8_t *dest, unsigned long *destLen,
206 const uint8_t *source, unsigned long sourceLen);</span>
207]]
208local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9313;</span>
209
210local function compress(txt)
211 local n = zlib.compressBound(#txt) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9314;</span>
212 local buf = ffi.new("uint8_t[?]", n)
213 local buflen = ffi.new("unsigned long[1]", n) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9315;</span>
214 local res = zlib.compress2(buf, buflen, txt, #txt, 9)
215 assert(res == 0)
216 return ffi.string(buf, buflen[0]) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9316;</span>
217end
218
219local function uncompress(comp, n) <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9317;</span>
220 local buf = ffi.new("uint8_t[?]", n)
221 local buflen = ffi.new("unsigned long[1]", n)
222 local res = zlib.uncompress(buf, buflen, comp, #comp)
223 assert(res == 0)
224 return ffi.string(buf, buflen[0])
225end
226
227-- Simple test code. <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">&#9318;</span>
228local txt = string.rep("abcd", 1000)
229print("Uncompressed size: ", #txt)
230local c = compress(txt)
231print("Compressed size: ", #c)
232local txt2 = uncompress(c, #txt)
233assert(txt2 == txt)
234</pre>
235<p>
236Here's the step-by-step explanation:
237</p>
238<p>
239<span style="color:#4040c0;">&#9312;</span> This defines some of the
240C&nbsp;functions provided by zlib. For the sake of this example, some
241type indirections have been reduced and it uses the pre-defined
242fixed-size integer types, while still adhering to the zlib API/ABI.
243</p>
244<p>
245<span style="color:#4040c0;">&#9313;</span> This loads the zlib shared
246library. On POSIX systems it's named <tt>libz.so</tt> and usually
247comes pre-installed. Since <tt>ffi.load()</tt> automatically adds any
248missing standard prefixes/suffixes, we can simply load the
249<tt>"z"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and
250you'll have to download it first from the
251<a href="http://zlib.net/"><span class="ext">&raquo;</span>&nbsp;zlib site</a>. The check for
252<tt>ffi.os</tt> makes sure we pass the right name to
253<tt>ffi.load()</tt>.
254</p>
255<p>
256<span style="color:#4040c0;">&#9314;</span> First, the maximum size of
257the compression buffer is obtained by calling the
258<tt>zlib.compressBound</tt> function with the length of the
259uncompressed string. The next line allocates a byte buffer of this
260size. The <tt>[?]</tt> in the type specification indicates a
261variable-length array (VLA). The actual number of elements of this
262array is given as the 2nd argument to <tt>ffi.new()</tt>.
263</p>
264<p>
265<span style="color:#4040c0;">&#9315;</span> This may look strange at
266first, but have a look at the declaration of the <tt>compress2</tt>
267function from zlib: the destination length is defined as a pointer!
268This is because you pass in the maximum buffer size and get back the
269actual length that was used.
270</p>
271<p>
272In C you'd pass in the address of a local variable
273(<tt>&amp;buflen</tt>). But since there's no address-of operator in
274Lua, we'll just pass in a one-element array. Conveniently it can be
275initialized with the maximum buffer size in one step. Calling the
276actual <tt>zlib.compress2</tt> function is then straightforward.
277</p>
278<p>
279<span style="color:#4040c0;">&#9316;</span> We want to return the
280compressed data as a Lua string, so we'll use <tt>ffi.string()</tt>.
281It needs a pointer to the start of the data and the actual length. The
282length has been returned in the <tt>buflen</tt> array, so we'll just
283get it from there.
284</p>
285<p style="font-size: 8pt;">
286Note that since the function returns now, the <tt>buf</tt> and
287<tt>buflen</tt> variables will eventually be garbage collected. This
288is fine, because <tt>ffi.string()</tt> has copied the contents to a
289newly created (interned) Lua string. If you plan to call this function
290lots of times, consider reusing the buffers and/or handing back the
291results in buffers instead of strings. This will reduce the overhead
292for garbage collection and string interning.
293</p>
294<p>
295<span style="color:#4040c0;">&#9317;</span> The <tt>uncompress</tt>
296functions does the exact opposite of the <tt>compress</tt> function.
297The compressed data doesn't include the size of the original string,
298so this needs to be passed in. Otherwise no surprises here.
299</p>
300<p>
301<span style="color:#4040c0;">&#9318;</span> The code, that makes use
302of the functions we just defined, is just plain Lua code. It doesn't
303need to know anything about the LuaJIT FFI &mdash; the convenience
304wrapper functions completely hide it.
305</p>
306<p>
307One major advantage of the LuaJIT FFI is that you are now able to
308write those wrappers <em>in Lua</em>. And at a fraction of the time it
309would cost you to create an extra C&nbsp;module using the Lua/C API.
310Many of the simpler C&nbsp;functions can probably be used directly
311from your Lua code, without any wrappers.
312</p>
313<p style="font-size: 8pt;">
314Side note: the zlib API uses the <tt>long</tt> type for passing
315lengths and sizes around. But all those zlib functions actually only
316deal with 32&nbsp;bit values. This is an unfortunate choice for a
317public API, but may be explained by zlib's history &mdash; we'll just
318have to deal with it.
319</p>
320<p style="font-size: 8pt;">
321First, you should know that a <tt>long</tt> is a 64&nbsp;bit type e.g.
322on POSIX/x64 systems, but a 32&nbsp;bit type on Windows/x64 and on
32332&nbsp;bit systems. Thus a <tt>long</tt> result can be either a plain
324Lua number or a boxed 64&nbsp;bit integer cdata object, depending on
325the target system.
326</p>
327<p style="font-size: 8pt;">
328Ok, so the <tt>ffi.*</tt> functions generally accept cdata objects
329wherever you'd want to use a number. That's why we get a away with
330passing <tt>n</tt> to <tt>ffi.string()</tt> above. But other Lua
331library functions or modules don't know how to deal with this. So for
332maximum portability one needs to use <tt>tonumber()</tt> on returned
333<tt>long</tt> results before passing them on. Otherwise the
334application might work on some systems, but would fail in a POSIX/x64
335environment.
336</p>
337
338<h2 id="idioms">Translating C&nbsp;Idioms</h2>
339<p>
340Here's a list of common C&nbsp;idioms and their translation to the
341LuaJIT FFI:
342</p>
343<table class="idiomtable">
344<tr class="idiomhead">
345<td class="idiomdesc">Idiom</td>
346<td class="idiomc">C&nbsp;code</td>
347<td class="idiomlua">Lua code</td>
348</tr>
349<tr class="odd separate">
350<td class="idiomdesc">Pointer dereference<br><tt>int *p;</tt></td><td class="idiomc"><tt>x = *p;<br>*p = y;</tt></td><td class="idiomlua"><tt>x = <b>p[0]</b><br><b>p[0]</b> = y</tt></td></tr>
351<tr class="even">
352<td class="idiomdesc">Pointer indexing<br><tt>int i, *p;</tt></td><td class="idiomc"><tt>x = p[i];<br>p[i+1] = y;</tt></td><td class="idiomlua"><tt>x = p[i]<br>p[i+1] = y</tt></td></tr>
353<tr class="odd">
354<td class="idiomdesc">Array indexing<br><tt>int i, a[];</tt></td><td class="idiomc"><tt>x = a[i];<br>a[i+1] = y;</tt></td><td class="idiomlua"><tt>x = a[i]<br>a[i+1] = y</tt></td></tr>
355<tr class="even separate">
356<td class="idiomdesc"><tt>struct</tt>/<tt>union</tt> dereference<br><tt>struct foo s;</tt></td><td class="idiomc"><tt>x = s.field;<br>s.field = y;</tt></td><td class="idiomlua"><tt>x = s.field<br>s.field = y</tt></td></tr>
357<tr class="odd">
358<td class="idiomdesc"><tt>struct</tt>/<tt>union</tt> pointer deref.<br><tt>struct foo *sp;</tt></td><td class="idiomc"><tt>x = sp->field;<br>sp->field = y;</tt></td><td class="idiomlua"><tt>x = <b>s.field</b><br><b>s.field</b> = y</tt></td></tr>
359<tr class="even separate">
360<td class="idiomdesc">Pointer arithmetic<br><tt>int i, *p;</tt></td><td class="idiomc"><tt>x = p + i;<br>y = p - i;</tt></td><td class="idiomlua"><tt>x = p + i<br>y = p - i</tt></td></tr>
361<tr class="odd">
362<td class="idiomdesc">Pointer difference<br><tt>int *p1, *p2;</tt></td><td class="idiomc"><tt>x = p1 - p2;</tt></td><td class="idiomlua"><tt>x = p1 - p2</tt></td></tr>
363<tr class="even">
364<td class="idiomdesc">Array element pointer<br><tt>int i, a[];</tt></td><td class="idiomc"><tt>x = &amp;a[i];</tt></td><td class="idiomlua"><tt>x = <b>a+i</b></tt></td></tr>
365<tr class="odd">
366<td class="idiomdesc">Cast pointer to address<br><tt>int *p;</tt></td><td class="idiomc"><tt>x = (intptr_t)p;</tt></td><td class="idiomlua"><tt>x = <b>tonumber(<br>&nbsp;ffi.cast("intptr_t",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p))</b></tt></td></tr>
367<tr class="even separate">
368<td class="idiomdesc">Functions with outargs<br><tt>void foo(int *inoutlen);</tt></td><td class="idiomc"><tt>int len = x;<br>foo(&amp;len);<br>y = len;</tt></td><td class="idiomlua"><tt><b>local len =<br>&nbsp;&nbsp;ffi.new("int[1]", x)<br>foo(len)<br>y = len[0]</b></tt></td></tr>
369<tr class="odd">
370<td class="idiomdesc"><a href="ext_ffi_semantics.html#convert_vararg">Vararg conversions</a><br><tt>int printf(char *fmt, ...);</tt></td><td class="idiomc"><tt>printf("%g", 1.0);<br>printf("%d", 1);<br>&nbsp;</tt></td><td class="idiomlua"><tt>printf("%g", 1);<br>printf("%d",<br>&nbsp;&nbsp;<b>ffi.new("int", 1)</b>)</tt></td></tr>
371</table>
372
373<h2 id="cache">To Cache or Not to Cache</h2>
374<p>
375It's a common Lua idiom to cache library functions in local variables
376or upvalues, e.g.:
377</p>
378<pre class="code">
379local byte, char = string.byte, string.char
380local function foo(x)
381 return char(byte(x)+1)
382end
383</pre>
384<p>
385This replaces several hash-table lookups with a (faster) direct use of
386a local or an upvalue. This is less important with LuaJIT, since the
387JIT compiler optimizes hash-table lookups a lot and is even able to
388hoist most of them out of the inner loops. It can't eliminate
389<em>all</em> of them, though, and it saves some typing for often-used
390functions. So there's still a place for this, even with LuaJIT.
391</p>
392<p>
393The situation is a bit different with C&nbsp;function calls via the
394FFI library. The JIT compiler has special logic to eliminate <em>all
395of the lookup overhead</em> for functions resolved from a
396<a href="ext_ffi_semantics.html#clib">C&nbsp;library namespace</a>!
397Thus it's not helpful and actually counter-productive to cache
398individual C&nbsp;functions like this:
399</p>
400<pre class="code">
401local <b>funca</b>, <b>funcb</b> = ffi.C.funcb, ffi.C.funcb -- <span style="color:#c00000;">Not helpful!</span>
402local function foo(x, n)
403 for i=1,n do <b>funcb</b>(<b>funca</b>(x, i), 1) end
404end
405</pre>
406<p>
407This turns them into indirect calls and generates bigger and slower
408machine code. Instead you'll want to cache the namespace itself and
409rely on the JIT compiler to eliminate the lookups:
410</p>
411<pre class="code">
412local <b>C</b> = ffi.C -- <span style="color:#00a000;">Instead use this!</span>
413local function foo(x, n)
414 for i=1,n do <b>C.funcb</b>(<b>C.funca</b>(x, i), 1) end
415end
416</pre>
417<p>
418This generates both shorter and faster code. So <b>don't cache
419C&nbsp;functions</b>, but <b>do</b> cache namespaces! Most often the
420namespace is already in a local variable at an outer scope, e.g. from
421<tt>local&nbsp;lib&nbsp;=&nbsp;ffi.load(...)</tt>. Note that copying
422it to a local variable in the function scope is unnecessary.
423</p>
80<br class="flush"> 424<br class="flush">
81</div> 425</div>
82<div id="foot"> 426<div id="foot">
diff --git a/doc/ext_jit.html b/doc/ext_jit.html
index 36e306a8..e8f5518e 100644
--- a/doc/ext_jit.html
+++ b/doc/ext_jit.html
@@ -33,8 +33,6 @@
33</li><li> 33</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a> 34<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li> 35</li><li>
36<a href="ext_ffi_int64.html">64 bit Integers</a>
37</li><li>
38<a href="ext_ffi_semantics.html">FFI Semantics</a> 36<a href="ext_ffi_semantics.html">FFI Semantics</a>
39</li></ul> 37</li></ul>
40</li><li> 38</li><li>
diff --git a/doc/extensions.html b/doc/extensions.html
index 8385727b..7d12299c 100644
--- a/doc/extensions.html
+++ b/doc/extensions.html
@@ -50,8 +50,6 @@ td.excinterop {
50</li><li> 50</li><li>
51<a href="ext_ffi_api.html">ffi.* API</a> 51<a href="ext_ffi_api.html">ffi.* API</a>
52</li><li> 52</li><li>
53<a href="ext_ffi_int64.html">64 bit Integers</a>
54</li><li>
55<a href="ext_ffi_semantics.html">FFI Semantics</a> 53<a href="ext_ffi_semantics.html">FFI Semantics</a>
56</li></ul> 54</li></ul>
57</li><li> 55</li><li>
diff --git a/doc/faq.html b/doc/faq.html
index 4ec69882..8de8c3f1 100644
--- a/doc/faq.html
+++ b/doc/faq.html
@@ -36,8 +36,6 @@ dd { margin-left: 1.5em; }
36</li><li> 36</li><li>
37<a href="ext_ffi_api.html">ffi.* API</a> 37<a href="ext_ffi_api.html">ffi.* API</a>
38</li><li> 38</li><li>
39<a href="ext_ffi_int64.html">64 bit Integers</a>
40</li><li>
41<a href="ext_ffi_semantics.html">FFI Semantics</a> 39<a href="ext_ffi_semantics.html">FFI Semantics</a>
42</li></ul> 40</li></ul>
43</li><li> 41</li><li>
diff --git a/doc/install.html b/doc/install.html
index 55de1bd8..220c326f 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -62,8 +62,6 @@ td.compatno {
62</li><li> 62</li><li>
63<a href="ext_ffi_api.html">ffi.* API</a> 63<a href="ext_ffi_api.html">ffi.* API</a>
64</li><li> 64</li><li>
65<a href="ext_ffi_int64.html">64 bit Integers</a>
66</li><li>
67<a href="ext_ffi_semantics.html">FFI Semantics</a> 65<a href="ext_ffi_semantics.html">FFI Semantics</a>
68</li></ul> 66</li></ul>
69</li><li> 67</li><li>
diff --git a/doc/luajit.html b/doc/luajit.html
index 131e4396..108ca18e 100644
--- a/doc/luajit.html
+++ b/doc/luajit.html
@@ -34,8 +34,6 @@
34</li><li> 34</li><li>
35<a href="ext_ffi_api.html">ffi.* API</a> 35<a href="ext_ffi_api.html">ffi.* API</a>
36</li><li> 36</li><li>
37<a href="ext_ffi_int64.html">64 bit Integers</a>
38</li><li>
39<a href="ext_ffi_semantics.html">FFI Semantics</a> 37<a href="ext_ffi_semantics.html">FFI Semantics</a>
40</li></ul> 38</li></ul>
41</li><li> 39</li><li>
diff --git a/doc/running.html b/doc/running.html
index cb96eabb..ba55e56d 100644
--- a/doc/running.html
+++ b/doc/running.html
@@ -55,8 +55,6 @@ td.param_default {
55</li><li> 55</li><li>
56<a href="ext_ffi_api.html">ffi.* API</a> 56<a href="ext_ffi_api.html">ffi.* API</a>
57</li><li> 57</li><li>
58<a href="ext_ffi_int64.html">64 bit Integers</a>
59</li><li>
60<a href="ext_ffi_semantics.html">FFI Semantics</a> 58<a href="ext_ffi_semantics.html">FFI Semantics</a>
61</li></ul> 59</li></ul>
62</li><li> 60</li><li>
diff --git a/doc/status.html b/doc/status.html
index 5ce3bf4c..eddbfb24 100644
--- a/doc/status.html
+++ b/doc/status.html
@@ -36,8 +36,6 @@ ul li { padding-bottom: 0.3em; }
36</li><li> 36</li><li>
37<a href="ext_ffi_api.html">ffi.* API</a> 37<a href="ext_ffi_api.html">ffi.* API</a>
38</li><li> 38</li><li>
39<a href="ext_ffi_int64.html">64 bit Integers</a>
40</li><li>
41<a href="ext_ffi_semantics.html">FFI Semantics</a> 39<a href="ext_ffi_semantics.html">FFI Semantics</a>
42</li></ul> 40</li></ul>
43</li><li> 41</li><li>