diff options
Diffstat (limited to 'doc/ext_ffi_semantics.html')
| -rw-r--r-- | doc/ext_ffi_semantics.html | 104 |
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">»</span></a> | 54 | <a href="https://luajit.org/status.html">Status <span class="ext">»</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><unistd.h></tt> (POSIX): <tt>ssize_t</tt>.</li> | ||
| 183 | |||
| 178 | </ul> | 184 | </ul> |
| 179 | <p> | 185 | <p> |
| 180 | You're encouraged to use these types in preference to | 186 | You'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">→<sup>round</sup></td><td class="convout"><tt>double</tt>, <tt>float</tt></td></tr> | 339 | <td class="convin">Integer</td><td class="convop">→<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">→<sup>trunc</sup> <tt>int32_t</tt> →<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">→<sup>trunc</sup> <tt>int64_t</tt> →<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">→<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">→<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">→<sup>trunc</sup> uint64_t ∪ int64_t →<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">→<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">→<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 → 0, otherwise 1</td><td class="convout"><tt>bool</tt></td></tr> | 349 | <td class="convin">Number</td><td class="convop">n == 0 → 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> → 0, <tt>true</tt> → 1</td><td class="convout">Number</td></tr> | 351 | <td class="convin"><tt>bool</tt></td><td class="convop"><tt>false</tt> → 0, <tt>true</tt> → 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. | |||
| 378 | Conversions not listed above will raise an error. E.g. it's not | 386 | Conversions not listed above will raise an error. E.g. it's not |
| 379 | possible to convert a pointer to a complex number or vice versa. | 387 | possible 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 | ||
| 391 | allow for mixed-signedness conversions, which are common in C code. | ||
| 392 | E.g. initializing an <tt>int32_t</tt> field with <tt>0xffffffff</tt> | ||
| 393 | or initializing an <tt>uint32_t</tt> or <tt>uint64_t</tt> field with | ||
| 394 | <tt>-1</tt>. Under strict conversion rules, these assignments would | ||
| 395 | give undefined results, since Lua numbers are doubles. The extended | ||
| 396 | ranges make these conversions defined. Lua numbers that are even | ||
| 397 | outside that range give an architecture-specific result. | ||
| 398 | </p> | ||
| 399 | <p> | ||
| 400 | Please note that doubles do not have the precision to represent the | ||
| 401 | whole signed or unsigned 64 bit integer range. Beware of large hex | ||
| 402 | constants in particular: e.g. <tt>0xffffffffffffffff</tt> is a double | ||
| 403 | rounded up to <tt>0x1p64</tt> during parsing. This will <em>not</em> | ||
| 404 | convert to a defined 64 bit integer value. Use the 64 bit literal | ||
| 405 | syntax instead, i.e. <tt>0xffffffffffffffffULL</tt>. | ||
| 406 | </p> | ||
| 381 | 407 | ||
| 382 | <h3 id="convert_vararg">Conversions for vararg C function arguments</h3> | 408 | <h3 id="convert_vararg">Conversions for vararg C function arguments</h3> |
| 383 | <p> | 409 | <p> |
| @@ -434,6 +460,19 @@ If you don't do this, the default Lua number → <tt>double</tt> | |||
| 434 | conversion rule applies. A vararg C function expecting an integer | 460 | conversion rule applies. A vararg C function expecting an integer |
| 435 | will see a garbled or uninitialized value. | 461 | will see a garbled or uninitialized value. |
| 436 | </p> | 462 | </p> |
| 463 | <p> | ||
| 464 | Note: this is the only place where creating a boxed scalar number type is | ||
| 465 | actually useful. <b>Never use <tt>ffi.new("int")</tt>, <tt>ffi.new("float")</tt> | ||
| 466 | etc. anywhere else!</b> | ||
| 467 | </p> | ||
| 468 | <p style="font-size: 8pt;"> | ||
| 469 | Ditto for <tt>ffi.cast()</tt>. Explicitly boxing scalars <b>does not</b> | ||
| 470 | improve performance or force <tt>int</tt> or <tt>float</tt> arithmetic! It | ||
| 471 | just adds costly boxing, unboxing and conversions steps. And it may lead | ||
| 472 | to surprise results, because | ||
| 473 | <a href="#cdata_arith">cdata arithmetic on scalar numbers</a> | ||
| 474 | is 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 bit integer to a Lua | |||
| 722 | number (e.g. for regular floating-point calculations) with | 761 | number (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 bit bitwise operations</b>: the rules for 64 bit | ||
| 765 | arithmetic operators apply analogously.<br> | ||
| 766 | |||
| 767 | Unlike the other <tt>bit.*</tt> operations, <tt>bit.tobit()</tt> | ||
| 768 | converts a cdata number via <tt>int64_t</tt> to <tt>int32_t</tt> and | ||
| 769 | returns a Lua number.<br> | ||
| 770 | |||
| 771 | For <tt>bit.band()</tt>, <tt>bit.bor()</tt> and <tt>bit.bxor()</tt>, the | ||
| 772 | conversion 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 | |||
| 775 | For all other operations, only the first argument is used to determine | ||
| 776 | the output type. This implies that a cdata number as a shift count for | ||
| 777 | shifts and rotates is accepted, but that alone does <em>not</em> cause | ||
| 778 | a 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 | |||
| 1193 | suboptimal performance, especially when used in inner loops: | 1248 | suboptimal 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 types |
| 1201 | <li>Allocations of C types with a size > 128 bytes or an | 1255 | (> 128 bytes or > 16 array elements).</li> |
| 1202 | alignment > 8 bytes.</li> | 1256 | <li>Bitfield initializations.</li> |
| 1203 | <li>Conversions from lightuserdata to <tt>void *</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 |
| 1205 | two.</li> | 1258 | two.</li> |
| 1206 | <li>Calls to C functions with aggregates passed or returned by | 1259 | <li>Calls to C functions with aggregates passed or returned by |
| @@ -1216,7 +1269,6 @@ value.</li> | |||
| 1216 | Other missing features: | 1269 | Other missing features: |
| 1217 | </p> | 1270 | </p> |
| 1218 | <ul> | 1271 | <ul> |
| 1219 | <li>Bit operations for 64 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 functions.</li> | 1273 | <li>Passing structs by value to vararg C functions.</li> |
| 1222 | <li><a href="extensions.html#exceptions">C++ exception interoperability</a> | 1274 | <li><a href="extensions.html#exceptions">C++ exception interoperability</a> |
