aboutsummaryrefslogtreecommitdiff
path: root/doc/ext_ffi_semantics.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ext_ffi_semantics.html')
-rw-r--r--doc/ext_ffi_semantics.html104
1 files changed, 78 insertions, 26 deletions
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html
index 806349ac..bf8d346d 100644
--- a/doc/ext_ffi_semantics.html
+++ b/doc/ext_ffi_semantics.html
@@ -1,8 +1,8 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 1<!DOCTYPE html>
2<html> 2<html>
3<head> 3<head>
4<title>FFI Semantics</title> 4<title>FFI Semantics</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 5<meta charset="utf-8">
6<meta name="Copyright" content="Copyright (C) 2005-2026"> 6<meta name="Copyright" content="Copyright (C) 2005-2026">
7<meta name="Language" content="en"> 7<meta name="Language" content="en">
8<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> 8<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
@@ -42,9 +42,13 @@ td.convop { font-style: italic; width: 40%; }
42<a class="current" href="ext_ffi_semantics.html">FFI Semantics</a> 42<a class="current" href="ext_ffi_semantics.html">FFI Semantics</a>
43</li></ul> 43</li></ul>
44</li><li> 44</li><li>
45<a href="ext_buffer.html">String Buffers</a>
46</li><li>
45<a href="ext_jit.html">jit.* Library</a> 47<a href="ext_jit.html">jit.* Library</a>
46</li><li> 48</li><li>
47<a href="ext_c_api.html">Lua/C API</a> 49<a href="ext_c_api.html">Lua/C API</a>
50</li><li>
51<a href="ext_profiler.html">Profiler</a>
48</li></ul> 52</li></ul>
49</li><li> 53</li><li>
50<a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a> 54<a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
@@ -175,6 +179,8 @@ a <tt>typedef</tt>, except re-declarations will be ignored):
175<tt>uint16_t</tt>, <tt>uint32_t</tt>, <tt>uint64_t</tt>, 179<tt>uint16_t</tt>, <tt>uint32_t</tt>, <tt>uint64_t</tt>,
176<tt>intptr_t</tt>, <tt>uintptr_t</tt>.</li> 180<tt>intptr_t</tt>, <tt>uintptr_t</tt>.</li>
177 181
182<li>From <tt>&lt;unistd.h&gt;</tt> (POSIX): <tt>ssize_t</tt>.</li>
183
178</ul> 184</ul>
179<p> 185<p>
180You're encouraged to use these types in preference to 186You're encouraged to use these types in preference to
@@ -332,42 +338,44 @@ pointer or type compatibility:
332<tr class="odd"> 338<tr class="odd">
333<td class="convin">Integer</td><td class="convop">&rarr;<sup>round</sup></td><td class="convout"><tt>double</tt>, <tt>float</tt></td></tr> 339<td class="convin">Integer</td><td class="convop">&rarr;<sup>round</sup></td><td class="convout"><tt>double</tt>, <tt>float</tt></td></tr>
334<tr class="even"> 340<tr class="even">
335<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>trunc</sup> <tt>int32_t</tt> &rarr;<sup>narrow</sup></td><td class="convout"><tt>(u)int8_t</tt>, <tt>(u)int16_t</tt></td></tr> 341<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>trunc</sup> <tt>int64_t</tt> &rarr;<sup>narrow</sup> <sup>*</sup></td><td class="convout"><tt>(u)int8_t</tt>, <tt>(u)int16_t</tt>, <tt>(u)int32_t</tt></td></tr>
336<tr class="odd"> 342<tr class="odd">
337<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>trunc</sup></td><td class="convout"><tt>(u)int32_t</tt>, <tt>(u)int64_t</tt></td></tr> 343<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>trunc</sup></td><td class="convout"><tt>int64_t</tt></td></tr>
338<tr class="even"> 344<tr class="even">
345<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>trunc</sup> uint64_t &cup; int64_t &rarr;<sup>reinterpret</sup> <sup>*</sup></td><td class="convout"><tt>uint64_t</tt></td></tr>
346<tr class="odd">
339<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>round</sup></td><td class="convout"><tt>float</tt>, <tt>double</tt></td></tr> 347<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>round</sup></td><td class="convout"><tt>float</tt>, <tt>double</tt></td></tr>
340<tr class="odd separate"> 348<tr class="even separate">
341<td class="convin">Number</td><td class="convop">n == 0 &rarr; 0, otherwise 1</td><td class="convout"><tt>bool</tt></td></tr> 349<td class="convin">Number</td><td class="convop">n == 0 &rarr; 0, otherwise 1</td><td class="convout"><tt>bool</tt></td></tr>
342<tr class="even"> 350<tr class="odd">
343<td class="convin"><tt>bool</tt></td><td class="convop"><tt>false</tt> &rarr; 0, <tt>true</tt> &rarr; 1</td><td class="convout">Number</td></tr> 351<td class="convin"><tt>bool</tt></td><td class="convop"><tt>false</tt> &rarr; 0, <tt>true</tt> &rarr; 1</td><td class="convout">Number</td></tr>
344<tr class="odd separate"> 352<tr class="even separate">
345<td class="convin">Complex number</td><td class="convop">convert real part</td><td class="convout">Number</td></tr> 353<td class="convin">Complex number</td><td class="convop">convert real part</td><td class="convout">Number</td></tr>
346<tr class="even">
347<td class="convin">Number</td><td class="convop">convert real part, imag = 0</td><td class="convout">Complex number</td></tr>
348<tr class="odd"> 354<tr class="odd">
355<td class="convin">Number</td><td class="convop">convert real part, imag = 0</td><td class="convout">Complex number</td></tr>
356<tr class="even">
349<td class="convin">Complex number</td><td class="convop">convert real and imag part</td><td class="convout">Complex number</td></tr> 357<td class="convin">Complex number</td><td class="convop">convert real and imag part</td><td class="convout">Complex number</td></tr>
350<tr class="even separate"> 358<tr class="odd separate">
351<td class="convin">Number</td><td class="convop">convert scalar and replicate</td><td class="convout">Vector</td></tr> 359<td class="convin">Number</td><td class="convop">convert scalar and replicate</td><td class="convout">Vector</td></tr>
352<tr class="odd"> 360<tr class="even">
353<td class="convin">Vector</td><td class="convop">copy (same size)</td><td class="convout">Vector</td></tr> 361<td class="convin">Vector</td><td class="convop">copy (same size)</td><td class="convout">Vector</td></tr>
354<tr class="even separate"> 362<tr class="odd separate">
355<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr> 363<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr>
356<tr class="odd">
357<td class="convin">Array</td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr>
358<tr class="even"> 364<tr class="even">
365<td class="convin">Array</td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr>
366<tr class="odd">
359<td class="convin">Function</td><td class="convop">take function address</td><td class="convout">Function pointer</td></tr> 367<td class="convin">Function</td><td class="convop">take function address</td><td class="convout">Function pointer</td></tr>
360<tr class="odd separate"> 368<tr class="even separate">
361<td class="convin">Number</td><td class="convop">convert via <tt>uintptr_t</tt> (cast)</td><td class="convout">Pointer</td></tr> 369<td class="convin">Number</td><td class="convop">convert via <tt>uintptr_t</tt> (cast)</td><td class="convout">Pointer</td></tr>
362<tr class="even">
363<td class="convin">Pointer</td><td class="convop">convert address (compat/cast)</td><td class="convout">Pointer</td></tr>
364<tr class="odd"> 370<tr class="odd">
365<td class="convin">Pointer</td><td class="convop">convert address (cast)</td><td class="convout">Integer</td></tr> 371<td class="convin">Pointer</td><td class="convop">convert address (compat/cast)</td><td class="convout">Pointer</td></tr>
366<tr class="even"> 372<tr class="even">
373<td class="convin">Pointer</td><td class="convop">convert address (cast)</td><td class="convout">Integer</td></tr>
374<tr class="odd">
367<td class="convin">Array</td><td class="convop">convert base address (cast)</td><td class="convout">Integer</td></tr> 375<td class="convin">Array</td><td class="convop">convert base address (cast)</td><td class="convout">Integer</td></tr>
368<tr class="odd separate"> 376<tr class="even separate">
369<td class="convin">Array</td><td class="convop">copy (compat)</td><td class="convout">Array</td></tr> 377<td class="convin">Array</td><td class="convop">copy (compat)</td><td class="convout">Array</td></tr>
370<tr class="even"> 378<tr class="odd">
371<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">copy (identical type)</td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr> 379<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">copy (identical type)</td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr>
372</table> 380</table>
373<p> 381<p>
@@ -378,6 +386,24 @@ type.
378Conversions not listed above will raise an error. E.g. it's not 386Conversions not listed above will raise an error. E.g. it's not
379possible to convert a pointer to a complex number or vice versa. 387possible to convert a pointer to a complex number or vice versa.
380</p> 388</p>
389<p>
390* Some conversions from <tt>double</tt> have a larger defined range to
391allow for mixed-signedness conversions, which are common in C code.
392E.g. initializing an <tt>int32_t</tt> field with <tt>0xffffffff</tt>
393or initializing an <tt>uint32_t</tt> or <tt>uint64_t</tt> field with
394<tt>-1</tt>. Under strict conversion rules, these assignments would
395give undefined results, since Lua numbers are doubles. The extended
396ranges make these conversions defined. Lua numbers that are even
397outside that range give an architecture-specific result.
398</p>
399<p>
400Please note that doubles do not have the precision to represent the
401whole signed or unsigned 64 bit integer range. Beware of large hex
402constants in particular: e.g. <tt>0xffffffffffffffff</tt> is a double
403rounded up to <tt>0x1p64</tt> during parsing. This will <em>not</em>
404convert to a defined 64 bit integer value. Use the 64 bit literal
405syntax instead, i.e. <tt>0xffffffffffffffffULL</tt>.
406</p>
381 407
382<h3 id="convert_vararg">Conversions for vararg C&nbsp;function arguments</h3> 408<h3 id="convert_vararg">Conversions for vararg C&nbsp;function arguments</h3>
383<p> 409<p>
@@ -434,6 +460,19 @@ If you don't do this, the default Lua number &rarr; <tt>double</tt>
434conversion rule applies. A vararg C&nbsp;function expecting an integer 460conversion rule applies. A vararg C&nbsp;function expecting an integer
435will see a garbled or uninitialized value. 461will see a garbled or uninitialized value.
436</p> 462</p>
463<p>
464Note: this is the only place where creating a boxed scalar number type is
465actually useful. <b>Never use <tt>ffi.new("int")</tt>, <tt>ffi.new("float")</tt>
466etc. anywhere else!</b>
467</p>
468<p style="font-size: 8pt;">
469Ditto for <tt>ffi.cast()</tt>. Explicitly boxing scalars <b>does not</b>
470improve performance or force <tt>int</tt> or <tt>float</tt> arithmetic! It
471just adds costly boxing, unboxing and conversions steps. And it may lead
472to surprise results, because
473<a href="#cdata_arith">cdata arithmetic on scalar numbers</a>
474is always performed on 64 bit integers.
475</p>
437 476
438<h2 id="init">Initializers</h2> 477<h2 id="init">Initializers</h2>
439<p> 478<p>
@@ -722,6 +761,22 @@ You'll have to explicitly convert a 64&nbsp;bit integer to a Lua
722number (e.g. for regular floating-point calculations) with 761number (e.g. for regular floating-point calculations) with
723<tt>tonumber()</tt>. But note this may incur a precision loss.</li> 762<tt>tonumber()</tt>. But note this may incur a precision loss.</li>
724 763
764<li><b>64&nbsp;bit bitwise operations</b>: the rules for 64&nbsp;bit
765arithmetic operators apply analogously.<br>
766
767Unlike the other <tt>bit.*</tt> operations, <tt>bit.tobit()</tt>
768converts a cdata number via <tt>int64_t</tt> to <tt>int32_t</tt> and
769returns a Lua number.<br>
770
771For <tt>bit.band()</tt>, <tt>bit.bor()</tt> and <tt>bit.bxor()</tt>, the
772conversion to <tt>int64_t</tt> or <tt>uint64_t</tt> applies to
773<em>all</em> arguments, if <em>any</em> argument is a cdata number.<br>
774
775For all other operations, only the first argument is used to determine
776the output type. This implies that a cdata number as a shift count for
777shifts and rotates is accepted, but that alone does <em>not</em> cause
778a cdata number output.
779
725</ul> 780</ul>
726 781
727<h3 id="cdata_comp">Comparisons of cdata objects</h3> 782<h3 id="cdata_comp">Comparisons of cdata objects</h3>
@@ -1193,14 +1248,12 @@ The following operations are currently not compiled and may exhibit
1193suboptimal performance, especially when used in inner loops: 1248suboptimal performance, especially when used in inner loops:
1194</p> 1249</p>
1195<ul> 1250<ul>
1196<li>Bitfield accesses and initializations.</li>
1197<li>Vector operations.</li> 1251<li>Vector operations.</li>
1198<li>Table initializers.</li> 1252<li>Table initializers.</li>
1199<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li> 1253<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>
1200<li>Allocations of variable-length arrays or structs.</li> 1254<li>Non-default initialization of VLA/VLS or large C&nbsp;types
1201<li>Allocations of C&nbsp;types with a size &gt; 128&nbsp;bytes or an 1255(&gt; 128&nbsp;bytes or &gt; 16 array elements).</li>
1202alignment &gt; 8&nbsp;bytes.</li> 1256<li>Bitfield initializations.</li>
1203<li>Conversions from lightuserdata to <tt>void&nbsp;*</tt>.</li>
1204<li>Pointer differences for element sizes that are not a power of 1257<li>Pointer differences for element sizes that are not a power of
1205two.</li> 1258two.</li>
1206<li>Calls to C&nbsp;functions with aggregates passed or returned by 1259<li>Calls to C&nbsp;functions with aggregates passed or returned by
@@ -1216,7 +1269,6 @@ value.</li>
1216Other missing features: 1269Other missing features:
1217</p> 1270</p>
1218<ul> 1271<ul>
1219<li>Bit operations for 64&nbsp;bit types.</li>
1220<li>Arithmetic for <tt>complex</tt> numbers.</li> 1272<li>Arithmetic for <tt>complex</tt> numbers.</li>
1221<li>Passing structs by value to vararg C&nbsp;functions.</li> 1273<li>Passing structs by value to vararg C&nbsp;functions.</li>
1222<li><a href="extensions.html#exceptions">C++ exception interoperability</a> 1274<li><a href="extensions.html#exceptions">C++ exception interoperability</a>