clean up docs

This commit is contained in:
TopchetoEU 2025-02-10 15:52:00 +02:00
parent a4f56a459a
commit 601e90b2e7
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
33 changed files with 2977 additions and 6401 deletions

View File

24
README
View File

@ -1,16 +1,24 @@
README for LuaJIT 2.1
---------------------
# LuaJIT 2.1
This is a fork of LuaJIT by TopchetoEU. A long-term goal of it is to implement Lua 5.4 and an optimizing interpreter that will (hopefully) replace the JIT.
## Why?
Mike Pall seems to have pretty much abandoned LuaJIT, as new code gets merged to the codebase only occasionally and no new major features have been released. Even Mike has said that he will no longer take donations.
I have taken it upon myself to understand, modernize and extend the codebase of LuaJIT to fit the demand of the 2020s. Will I succeed? Probably not...
## About LuaJIT
LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
Project Homepage: https://luajit.org/
Mike Pall's LuaJIT homepage: https://luajit.org/
LuaJIT is Copyright (C) 2005-2025 Mike Pall.
This project is almost fully based on Mike Pall's version: Copyright (C) 2005-2025 Mike Pall.
LuaJIT is free software, released under the MIT license.
See full Copyright Notice in the COPYRIGHT file or in luajit.h.
Documentation for LuaJIT is available in HTML format.
Please point your favorite browser to:
doc/luajit.html
## Documentation
Currently, the documentation is available [here](./doc/index.md), a direct one-to-one translation from the (shitty) HTML of Mike's version. Read it to get acquainted with the basic components of the JIT

View File

@ -1,166 +0,0 @@
/* Copyright (C) 2004-2025 Mike Pall.
*
* You are welcome to use the general ideas of this design for your own sites.
* But please do not steal the stylesheet, the layout or the color scheme.
*/
body {
font-family: serif;
font-size: 11pt;
margin: 0 3em;
padding: 0;
border: none;
}
a:link, a:visited, a:hover, a:active {
text-decoration: none;
background: transparent;
color: #0000ff;
}
h1, h2, h3 {
font-family: sans-serif;
font-weight: bold;
text-align: left;
margin: 0.5em 0;
padding: 0;
}
h1 {
font-size: 200%;
}
h2 {
font-size: 150%;
}
h3 {
font-size: 125%;
}
p {
margin: 0 0 0.5em 0;
padding: 0;
}
ul, ol {
margin: 0.5em 0;
padding: 0 0 0 2em;
}
ul {
list-style: outside square;
}
ol {
list-style: outside decimal;
}
li {
margin: 0;
padding: 0;
}
dl {
margin: 1em 0;
padding: 1em;
border: 1px solid black;
}
dt {
font-weight: bold;
margin: 0;
padding: 0;
}
dt sup {
float: right;
margin-left: 1em;
}
dd {
margin: 0.5em 0 0 2em;
padding: 0;
}
table {
table-layout: fixed;
width: 100%;
margin: 1em 0;
padding: 0;
border: 1px solid black;
border-spacing: 0;
border-collapse: collapse;
}
tr {
margin: 0;
padding: 0;
border: none;
}
td {
text-align: left;
margin: 0;
padding: 0.2em 0.5em;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
tr.separate td {
border-top: double;
}
tt, pre, code, kbd, samp {
font-family: monospace;
font-size: 75%;
}
kbd {
font-weight: bolder;
}
blockquote, pre {
margin: 1em 2em;
padding: 0;
}
img {
border: none;
vertical-align: baseline;
margin: 0;
padding: 0;
}
img.left {
float: left;
margin: 0.5em 1em 0.5em 0;
}
img.right {
float: right;
margin: 0.5em 0 0.5em 1em;
}
.flush {
clear: both;
visibility: hidden;
}
.hide, .noprint, #nav {
display: none !important;
}
.pagebreak {
page-break-before: always;
}
#site {
text-align: right;
font-family: sans-serif;
font-weight: bold;
margin: 0 1em;
border-bottom: 1pt solid black;
}
#site a {
font-size: 1.2em;
}
#site a:link, #site a:visited {
text-decoration: none;
font-weight: bold;
background: transparent;
color: #ffffff;
}
#logo {
color: #ff8000;
}
#head {
clear: both;
margin: 0 1em;
}
#main {
line-height: 1.3;
text-align: justify;
margin: 1em;
}
#foot {
clear: both;
font-size: 80%;
text-align: center;
margin: 0 1.25em;
padding: 0.5em 0 0 0;
border-top: 1pt solid black;
page-break-before: avoid;
page-break-after: avoid;
}

View File

@ -1,323 +0,0 @@
/* Copyright (C) 2004-2025 Mike Pall.
*
* You are welcome to use the general ideas of this design for your own sites.
* But please do not steal the stylesheet, the layout or the color scheme.
*/
/* colorscheme:
*
* site | head #4162bf/white | #6078bf/#e6ecff
* ------+------ ----------------+-------------------
* nav | main #bfcfff | #e6ecff/black
*
* nav: hiback loback #c5d5ff #b9c9f9
* hiborder loborder #e6ecff #97a7d7
* link hover #2142bf #ff0000
*
* link: link visited hover #2142bf #8122bf #ff0000
*
* main: boxback boxborder #f0f4ff #bfcfff
*/
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10pt;
margin: 0;
padding: 0;
border: none;
background: #e0e0e0;
color: #000000;
}
a:link {
text-decoration: none;
background: transparent;
color: #2142bf;
}
a:visited {
text-decoration: none;
background: transparent;
color: #8122bf;
}
a:hover, a:active {
text-decoration: underline;
background: transparent;
color: #ff0000;
}
h1, h2, h3 {
font-weight: bold;
text-align: left;
margin: 0.5em 0;
padding: 0;
background: transparent;
}
h1 {
font-size: 200%;
line-height: 3em; /* really 6em relative to body, match #site span */
margin: 0;
}
h2 {
font-size: 150%;
color: #606060;
}
h3 {
font-size: 125%;
color: #404040;
}
p {
max-width: 600px;
margin: 0 0 0.5em 0;
padding: 0;
}
b {
color: #404040;
}
ul, ol {
max-width: 600px;
margin: 0.5em 0;
padding: 0 0 0 2em;
}
ul {
list-style: outside square;
}
ol {
list-style: outside decimal;
}
li {
margin: 0;
padding: 0;
}
dl {
max-width: 600px;
margin: 1em 0;
padding: 1em;
border: 1px solid #bfcfff;
background: #f0f4ff;
}
dt {
font-weight: bold;
margin: 0;
padding: 0;
}
dt sup {
float: right;
margin-left: 1em;
color: #808080;
}
dt a:visited {
text-decoration: none;
color: #2142bf;
}
dt a:hover, dt a:active {
text-decoration: none;
color: #ff0000;
}
dd {
margin: 0.5em 0 0 2em;
padding: 0;
}
div.tablewrap { /* for IE *sigh* */
max-width: 600px;
}
table {
table-layout: fixed;
border-spacing: 0;
border-collapse: collapse;
max-width: 600px;
width: 100%;
margin: 1em 0;
padding: 0;
border: 1px solid #bfcfff;
}
tr {
margin: 0;
padding: 0;
border: none;
}
tr.odd {
background: #f0f4ff;
}
tr.separate td {
border-top: 1px solid #bfcfff;
}
td {
text-align: left;
margin: 0;
padding: 0.2em 0.5em;
border: none;
}
tt, code, kbd, samp {
font-family: Courier New, Courier, monospace;
line-height: 1.2;
font-size: 110%;
}
kbd {
font-weight: bolder;
}
blockquote, pre {
max-width: 600px;
margin: 1em 2em;
padding: 0;
}
pre {
line-height: 1.1;
}
pre.code {
line-height: 1.4;
margin: 0.5em 0 1em 0.5em;
padding: 0.5em 1em;
border: 1px solid #bfcfff;
background: #f0f4ff;
}
pre.mark {
padding-left: 2em;
}
span.codemark {
position:absolute;
left: 16em;
color: #4040c0;
}
span.mark {
color: #4040c0;
font-family: Courier New, Courier, monospace;
line-height: 1.1;
}
img {
border: none;
vertical-align: baseline;
margin: 0;
padding: 0;
}
img.left {
float: left;
margin: 0.5em 1em 0.5em 0;
}
img.right {
float: right;
margin: 0.5em 0 0.5em 1em;
}
.indent {
padding-left: 1em;
}
.flush {
clear: both;
visibility: hidden;
}
.hide, .noscreen {
display: none !important;
}
.ext {
color: #ff8000;
}
.note {
padding: 0.5em 1em;
border-left: 3px solid #bfcfff;
}
#site {
clear: both;
float: left;
width: 13em;
text-align: center;
font-weight: bold;
margin: 0;
padding: 0;
background: transparent;
color: #ffffff;
}
#site a {
font-size: 200%;
}
#site a:link, #site a:visited {
text-decoration: none;
font-weight: bold;
background: transparent;
color: #ffffff;
}
#site span {
line-height: 3em; /* really 6em relative to body, match h1 */
}
#logo {
color: #ffb380;
}
#head {
margin: 0;
padding: 0 0 0 2em;
border-left: solid 13em #4162bf;
border-right: solid 3em #6078bf;
background: #6078bf;
color: #e6ecff;
}
#nav {
clear: both;
float: left;
overflow: hidden;
text-align: left;
line-height: 1.5;
width: 13em;
padding-top: 1em;
background: transparent;
}
#nav ul {
list-style: none outside;
margin: 0;
padding: 0;
}
#nav li {
margin: 0;
padding: 0;
}
#nav a {
display: block;
text-decoration: none;
font-weight: bold;
margin: 0;
padding: 2px 1em;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
background: transparent;
color: #2142bf;
}
#nav a:hover, #nav a:active {
text-decoration: none;
border-top: 1px solid #97a7d7;
border-bottom: 1px solid #e6ecff;
background: #b9c9f9;
color: #ff0000;
}
#nav a.current, #nav a.current:hover, #nav a.current:active {
border-top: 1px solid #e6ecff;
border-bottom: 1px solid #97a7d7;
background: #c5d5ff;
color: #2142bf;
}
#nav ul ul a {
padding: 0 1em 0 1.7em;
}
#nav ul ul ul a {
padding: 0 0.5em 0 2.4em;
}
#main {
line-height: 1.5;
text-align: left;
margin: 0;
padding: 1em 2em;
border-left: solid 13em #bfcfff;
border-right: solid 3em #e6ecff;
background: #e6ecff;
}
#foot {
clear: both;
font-size: 80%;
text-align: center;
margin: 0;
padding: 0.5em;
background: #6078bf;
color: #ffffff;
}
#foot a:link, #foot a:visited {
text-decoration: underline;
background: transparent;
color: #ffffff;
}
#foot a:hover, #foot a:active {
text-decoration: underline;
background: transparent;
color: #bfcfff;
}

View File

@ -1,112 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Contact</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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>Contact</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 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
If you want to report bugs, propose fixes or suggest enhancements,
please use the
<a href="https://github.com/LuaJIT/LuaJIT/issues"><span class="ext">&raquo;</span>&nbsp;GitHub issue tracker</a>.
</p>
<p>
Please send general questions to the
<a href="https://luajit.org/list.html"><span class="ext">&raquo;</span>&nbsp;LuaJIT mailing list</a>.
</p>
<p>
You can also send any questions you have directly to me:
</p>
<script type="text/javascript">
<!--
var xS="@-:\" .0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ<abc>defghijklmnopqrstuvwxyz";function xD(s)
{var len=s.length;var r="";for(var i=0;i<len;i++)
{var c=s.charAt(i);var n=xS.indexOf(c);if(n!=-1)c=xS.charAt(69-n);r+=c;}
document.write("<"+"p>"+r+"<"+"/p>\n");}
//-->
</script>
<script type="text/javascript">
<!--
xD("fyZKB8xv\"FJytmz8.KAB0u52D")
//--></script>
<noscript>
<p><img src="img/contact.png" alt="Contact info in image" width="170" height="13">
</p>
</noscript>
<p><i>
Note: I cannot reply to GMail, Google Workplace, Outlook or Office365
mail addresses, since they prefer to mindlessly filter out mails sent
from small domains using independent mail servers, such as mine. If you
don't like that, please complain to Google or Microsoft, not me.
</i></p>
<h2>Copyright</h2>
<p>
All documentation is
Copyright &copy; 2005-2025 Mike Pall.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

14
doc/contact.md Normal file
View File

@ -0,0 +1,14 @@
# Contact
If you want to report bugs, propose fixes or suggest enhancements, please use the [» GitHub issue tracker](https://github.com/LuaJIT/LuaJIT/issues).
Please send general questions to the [» LuaJIT mailing list](https://luajit.org/list.html).
You can also send any questions you have directly to me: web-07@luajit.org
*Note: I cannot reply to GMail, Google Workplace, Outlook or Office365 mail addresses, since they prefer to mindlessly filter out mails sent from small domains using independent mail servers, such as mine. If you don't like that, please complain to Google or Microsoft, not me.*
## Copyright
All documentation is Copyright © 2005-2025 Mike Pall.
Reformatted and converted to Markdown by TopchetoEU /w pandoc

166
doc/css/bluequad-print.css Normal file
View File

@ -0,0 +1,166 @@
/* Copyright (C) 2004-2025 Mike Pall.
*
* You are welcome to use the general ideas of this design for your own sites.
* But please do not steal the stylesheet, the layout or the color scheme.
*/
body {
font-family: serif;
font-size: 11pt;
margin: 0 3em;
padding: 0;
border: none;
}
a:link, a:visited, a:hover, a:active {
text-decoration: none;
background: transparent;
color: #0000ff;
}
h1, h2, h3 {
font-family: sans-serif;
font-weight: bold;
text-align: left;
margin: 0.5em 0;
padding: 0;
}
h1 {
font-size: 200%;
}
h2 {
font-size: 150%;
}
h3 {
font-size: 125%;
}
p {
margin: 0 0 0.5em 0;
padding: 0;
}
ul, ol {
margin: 0.5em 0;
padding: 0 0 0 2em;
}
ul {
list-style: outside square;
}
ol {
list-style: outside decimal;
}
li {
margin: 0;
padding: 0;
}
dl {
margin: 1em 0;
padding: 1em;
border: 1px solid black;
}
dt {
font-weight: bold;
margin: 0;
padding: 0;
}
dt sup {
float: right;
margin-left: 1em;
}
dd {
margin: 0.5em 0 0 2em;
padding: 0;
}
table {
table-layout: fixed;
width: 100%;
margin: 1em 0;
padding: 0;
border: 1px solid black;
border-spacing: 0;
border-collapse: collapse;
}
tr {
margin: 0;
padding: 0;
border: none;
}
td {
text-align: left;
margin: 0;
padding: 0.2em 0.5em;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
tr.separate td {
border-top: double;
}
tt, pre, code, kbd, samp {
font-family: monospace;
font-size: 75%;
}
kbd {
font-weight: bolder;
}
blockquote, pre {
margin: 1em 2em;
padding: 0;
}
img {
border: none;
vertical-align: baseline;
margin: 0;
padding: 0;
}
img.left {
float: left;
margin: 0.5em 1em 0.5em 0;
}
img.right {
float: right;
margin: 0.5em 0 0.5em 1em;
}
.flush {
clear: both;
visibility: hidden;
}
.hide, .noprint, #nav {
display: none !important;
}
.pagebreak {
page-break-before: always;
}
#site {
text-align: right;
font-family: sans-serif;
font-weight: bold;
margin: 0 1em;
border-bottom: 1pt solid black;
}
#site a {
font-size: 1.2em;
}
#site a:link, #site a:visited {
text-decoration: none;
font-weight: bold;
background: transparent;
color: #ffffff;
}
#logo {
color: #ff8000;
}
#head {
clear: both;
margin: 0 1em;
}
#main {
line-height: 1.3;
text-align: justify;
margin: 1em;
}
#foot {
clear: both;
font-size: 80%;
text-align: center;
margin: 0 1.25em;
padding: 0.5em 0 0 0;
border-top: 1pt solid black;
page-break-before: avoid;
page-break-after: avoid;
}

324
doc/css/bluequad.css Normal file
View File

@ -0,0 +1,324 @@
/* Copyright (C) 2004-2025 Mike Pall.
*
* You are welcome to use the general ideas of this design for your own sites.
* But please do not steal the stylesheet, the layout or the color scheme.
*/
/* colorscheme:
*
* site | head #4162bf/white | #6078bf/#e6ecff
* ------+------ ----------------+-------------------
* nav | main #bfcfff | #e6ecff/black
*
* nav: hiback loback #c5d5ff #b9c9f9
* hiborder loborder #e6ecff #97a7d7
* link hover #2142bf #ff0000
*
* link: link visited hover #2142bf #8122bf #ff0000
*
* main: boxback boxborder #f0f4ff #bfcfff
*/
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10pt;
margin: 0;
padding: 0;
border: none;
background: #e0e0e0;
color: #000000;
}
a:link {
text-decoration: none;
background: transparent;
color: #2142bf;
}
a:visited {
text-decoration: none;
background: transparent;
color: #8122bf;
}
a:hover, a:active {
text-decoration: underline;
background: transparent;
color: #ff0000;
}
h1, h2, h3 {
font-weight: bold;
text-align: left;
margin: 0.5em 0;
padding: 0;
background: transparent;
}
h1 {
font-size: 200%;
line-height: 3em; /* really 6em relative to body, match #site span */
margin: 0;
}
h2 {
font-size: 150%;
color: #606060;
}
h3 {
font-size: 125%;
color: #404040;
}
p {
max-width: 600px;
margin: 0 0 0.5em 0;
padding: 0;
}
b {
color: #404040;
}
ul, ol {
max-width: 600px;
margin: 0.5em 0;
padding: 0 0 0 2em;
}
ul {
list-style: outside square;
}
ol {
list-style: outside decimal;
}
li {
margin: 0;
padding: 0;
}
dl {
max-width: 600px;
margin: 1em 0;
padding: 1em;
border: 1px solid #bfcfff;
background: #f0f4ff;
}
dt {
font-weight: bold;
margin: 0;
padding: 0;
}
dt sup {
float: right;
margin-left: 1em;
color: #808080;
}
dt a:visited {
text-decoration: none;
color: #2142bf;
}
dt a:hover, dt a:active {
text-decoration: none;
color: #ff0000;
}
dd {
margin: 0.5em 0 0 2em;
padding: 0;
}
div.tablewrap {
/* for IE *sigh* */
max-width: 600px;
}
table {
table-layout: fixed;
border-spacing: 0;
border-collapse: collapse;
max-width: 600px;
width: 100%;
margin: 1em 0;
padding: 0;
border: 1px solid #bfcfff;
}
tr {
margin: 0;
padding: 0;
border: none;
}
tr.odd {
background: #f0f4ff;
}
tr.separate td {
border-top: 1px solid #bfcfff;
}
td {
text-align: left;
margin: 0;
padding: 0.2em 0.5em;
border: none;
}
tt, code, kbd, samp {
font-family: Courier New, Courier, monospace;
line-height: 1.2;
font-size: 110%;
}
kbd {
font-weight: bolder;
}
blockquote, pre {
max-width: 600px;
margin: 1em 2em;
padding: 0;
}
pre {
line-height: 1.1;
}
pre.code {
line-height: 1.4;
margin: 0.5em 0 1em 0.5em;
padding: 0.5em 1em;
border: 1px solid #bfcfff;
background: #f0f4ff;
}
pre.mark {
padding-left: 2em;
}
span.codemark {
position: absolute;
left: 16em;
color: #4040c0;
}
span.mark {
color: #4040c0;
font-family: Courier New, Courier, monospace;
line-height: 1.1;
}
img {
border: none;
vertical-align: baseline;
margin: 0;
padding: 0;
}
img.left {
float: left;
margin: 0.5em 1em 0.5em 0;
}
img.right {
float: right;
margin: 0.5em 0 0.5em 1em;
}
.indent {
padding-left: 1em;
}
.flush {
clear: both;
visibility: hidden;
}
.hide, .noscreen {
display: none !important;
}
.ext {
color: #ff8000;
}
.note {
padding: 0.5em 1em;
border-left: 3px solid #bfcfff;
}
#site {
clear: both;
float: left;
width: 13em;
text-align: center;
font-weight: bold;
margin: 0;
padding: 0;
background: transparent;
color: #ffffff;
}
#site a {
font-size: 200%;
}
#site a:link, #site a:visited {
text-decoration: none;
font-weight: bold;
background: transparent;
color: #ffffff;
}
#site span {
line-height: 3em; /* really 6em relative to body, match h1 */
}
#logo {
color: #ffb380;
}
#head {
margin: 0;
padding: 0 0 0 2em;
border-left: solid 13em #4162bf;
border-right: solid 3em #6078bf;
background: #6078bf;
color: #e6ecff;
}
#nav {
clear: both;
float: left;
overflow: hidden;
text-align: left;
line-height: 1.5;
width: 13em;
padding-top: 1em;
background: transparent;
}
#nav ul {
list-style: none outside;
margin: 0;
padding: 0;
}
#nav li {
margin: 0;
padding: 0;
}
#nav a {
display: block;
text-decoration: none;
font-weight: bold;
margin: 0;
padding: 2px 1em;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
background: transparent;
color: #2142bf;
}
#nav a:hover, #nav a:active {
text-decoration: none;
border-top: 1px solid #97a7d7;
border-bottom: 1px solid #e6ecff;
background: #b9c9f9;
color: #ff0000;
}
#nav a.current, #nav a.current:hover, #nav a.current:active {
border-top: 1px solid #e6ecff;
border-bottom: 1px solid #97a7d7;
background: #c5d5ff;
color: #2142bf;
}
#nav ul ul a {
padding: 0 1em 0 1.7em;
}
#nav ul ul ul a {
padding: 0 0.5em 0 2.4em;
}
#main {
line-height: 1.5;
text-align: left;
margin: 0;
padding: 1em 2em;
border-left: solid 13em #bfcfff;
border-right: solid 3em #e6ecff;
background: #e6ecff;
}
#foot {
clear: both;
font-size: 80%;
text-align: center;
margin: 0;
padding: 0.5em;
background: #6078bf;
color: #ffffff;
}
#foot a:link, #foot a:visited {
text-decoration: underline;
background: transparent;
color: #ffffff;
}
#foot a:hover, #foot a:active {
text-decoration: underline;
background: transparent;
color: #bfcfff;
}

View File

@ -1,689 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>String Buffer Library</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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">
.lib {
vertical-align: middle;
margin-left: 5px;
padding: 0 5px;
font-size: 60%;
border-radius: 5px;
background: #c5d5ff;
color: #000;
}
</style>
</head>
<body>
<div id="site">
<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1>String Buffer 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 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 class="current" 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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 string buffer library allows <b>high-performance manipulation of
string-like data</b>.
</p>
<p>
Unlike Lua strings, which are constants, string buffers are
<b>mutable</b> sequences of 8-bit (binary-transparent) characters. Data
can be stored, formatted and encoded into a string buffer and later
converted, extracted or decoded.
</p>
<p>
The convenient string buffer API simplifies common string manipulation
tasks, that would otherwise require creating many intermediate strings.
String buffers improve performance by eliminating redundant memory
copies, object creation, string interning and garbage collection
overhead. In conjunction with the FFI library, they allow zero-copy
operations.
</p>
<p>
The string buffer library also includes a high-performance
<a href="#serialize">serializer</a> for Lua objects.
</p>
<h2 id="use">Using the String Buffer Library</h2>
<p>
The string buffer library is built into LuaJIT by default, but it's not
loaded by default. Add this to the start of every Lua file that needs
one of its functions:
</p>
<pre class="code">
local buffer = require("string.buffer")
</pre>
<p>
The convention for the syntax shown on this page is that <tt>buffer</tt>
refers to the buffer library and <tt>buf</tt> refers to an individual
buffer object.
</p>
<p>
Please note the difference between a Lua function call, e.g.
<tt>buffer.new()</tt> (with a dot) and a Lua method call, e.g.
<tt>buf:reset()</tt> (with a colon).
</p>
<h3 id="buffer_object">Buffer Objects</h3>
<p>
A buffer object is a garbage-collected Lua object. After creation with
<tt>buffer.new()</tt>, it can (and should) be reused for many operations.
When the last reference to a buffer object is gone, it will eventually
be freed by the garbage collector, along with the allocated buffer
space.
</p>
<p>
Buffers operate like a FIFO (first-in first-out) data structure. Data
can be appended (written) to the end of the buffer and consumed (read)
from the front of the buffer. These operations may be freely mixed.
</p>
<p>
The buffer space that holds the characters is managed automatically
&mdash; it grows as needed and already consumed space is recycled. Use
<tt>buffer.new(size)</tt> and <tt>buf:free()</tt>, if you need more
control.
</p>
<p>
The maximum size of a single buffer is the same as the maximum size of a
Lua string, which is slightly below two gigabytes. For huge data sizes,
neither strings nor buffers are the right data structure &mdash; use the
FFI library to directly map memory or files up to the virtual memory
limit of your OS.
</p>
<h3 id="buffer_overview">Buffer Method Overview</h3>
<ul>
<li>
The <tt>buf:put*()</tt>-like methods append (write) characters to the
end of the buffer.
</li>
<li>
The <tt>buf:get*()</tt>-like methods consume (read) characters from the
front of the buffer.
</li>
<li>
Other methods, like <tt>buf:tostring()</tt> only read the buffer
contents, but don't change the buffer.
</li>
<li>
The <tt>buf:set()</tt> method allows zero-copy consumption of a string
or an FFI cdata object as a buffer.
</li>
<li>
The FFI-specific methods allow zero-copy read/write-style operations or
modifying the buffer contents in-place. Please check the
<a href="#ffi_caveats">FFI caveats</a> below, too.
</li>
<li>
Methods that don't need to return anything specific, return the buffer
object itself as a convenience. This allows method chaining, e.g.:
<tt>buf:reset():encode(obj)</tt> or <tt>buf:skip(len):get()</tt>
</li>
</ul>
<h2 id="create">Buffer Creation and Management</h2>
<h3 id="buffer_new"><tt>local buf = buffer.new([size [,options]])<br>
local buf = buffer.new([options])</tt></h3>
<p>
Creates a new buffer object.
</p>
<p>
The optional <tt>size</tt> argument ensures a minimum initial buffer
size. This is strictly an optimization when the required buffer size is
known beforehand. The buffer space will grow as needed, in any case.
</p>
<p>
The optional table <tt>options</tt> sets various
<a href="#serialize_options">serialization options</a>.
</p>
<h3 id="buffer_reset"><tt>buf = buf:reset()</tt></h3>
<p>
Reset (empty) the buffer. The allocated buffer space is not freed and
may be reused.
</p>
<h3 id="buffer_free"><tt>buf = buf:free()</tt></h3>
<p>
The buffer space of the buffer object is freed. The object itself
remains intact, empty and may be reused.
</p>
<p>
Note: you normally don't need to use this method. The garbage collector
automatically frees the buffer space, when the buffer object is
collected. Use this method, if you need to free the associated memory
immediately.
</p>
<h2 id="write">Buffer Writers</h2>
<h3 id="buffer_put"><tt>buf = buf:put([str|num|obj] [,…])</tt></h3>
<p>
Appends a string <tt>str</tt>, a number <tt>num</tt> or any object
<tt>obj</tt> with a <tt>__tostring</tt> metamethod to the buffer.
Multiple arguments are appended in the given order.
</p>
<p>
Appending a buffer to a buffer is possible and short-circuited
internally. But it still involves a copy. Better combine the buffer
writes to use a single buffer.
</p>
<h3 id="buffer_putf"><tt>buf = buf:putf(format, …)</tt></h3>
<p>
Appends the formatted arguments to the buffer. The <tt>format</tt>
string supports the same options as <tt>string.format()</tt>.
</p>
<h3 id="buffer_putcdata"><tt>buf = buf:putcdata(cdata, len)</tt><span class="lib">FFI</span></h3>
<p>
Appends the given <tt>len</tt> number of bytes from the memory pointed
to by the FFI <tt>cdata</tt> object to the buffer. The object needs to
be convertible to a (constant) pointer.
</p>
<h3 id="buffer_set"><tt>buf = buf:set(str)<br>
buf = buf:set(cdata, len)</tt><span class="lib">FFI</span></h3>
<p>
This method allows zero-copy consumption of a string or an FFI cdata
object as a buffer. It stores a reference to the passed string
<tt>str</tt> or the FFI <tt>cdata</tt> object in the buffer. Any buffer
space originally allocated is freed. This is <i>not</i> an append
operation, unlike the <tt>buf:put*()</tt> methods.
</p>
<p>
After calling this method, the buffer behaves as if
<tt>buf:free():put(str)</tt> or <tt>buf:free():put(cdata,&nbsp;len)</tt>
had been called. However, the data is only referenced and not copied, as
long as the buffer is only consumed.
</p>
<p>
In case the buffer is written to later on, the referenced data is copied
and the object reference is removed (copy-on-write semantics).
</p>
<p>
The stored reference is an anchor for the garbage collector and keeps the
originally passed string or FFI cdata object alive.
</p>
<h3 id="buffer_reserve"><tt>ptr, len = buf:reserve(size)</tt><span class="lib">FFI</span><br>
<tt>buf = buf:commit(used)</tt><span class="lib">FFI</span></h3>
<p>
The <tt>reserve</tt> method reserves at least <tt>size</tt> bytes of
write space in the buffer. It returns an <tt>uint8_t&nbsp;*</tt> FFI
cdata pointer <tt>ptr</tt> that points to this space.
</p>
<p>
The available length in bytes is returned in <tt>len</tt>. This is at
least <tt>size</tt> bytes, but may be more to facilitate efficient
buffer growth. You can either make use of the additional space or ignore
<tt>len</tt> and only use <tt>size</tt> bytes.
</p>
<p>
The <tt>commit</tt> method appends the <tt>used</tt> bytes of the
previously returned write space to the buffer data.
</p>
<p>
This pair of methods allows zero-copy use of C read-style APIs:
</p>
<pre class="code">
local MIN_SIZE = 65536
repeat
local ptr, len = buf:reserve(MIN_SIZE)
local n = C.read(fd, ptr, len)
if n == 0 then break end -- EOF.
if n &lt; 0 then error("read error") end
buf:commit(n)
until false
</pre>
<p>
The reserved write space is <i>not</i> initialized. At least the
<tt>used</tt> bytes <b>must</b> be written to before calling the
<tt>commit</tt> method. There's no need to call the <tt>commit</tt>
method, if nothing is added to the buffer (e.g. on error).
</p>
<h2 id="read">Buffer Readers</h2>
<h3 id="buffer_length"><tt>len = #buf</tt></h3>
<p>
Returns the current length of the buffer data in bytes.
</p>
<h3 id="buffer_concat"><tt>res = str|num|buf .. str|num|buf […]</tt></h3>
<p>
The Lua concatenation operator <tt>..</tt> also accepts buffers, just
like strings or numbers. It always returns a string and not a buffer.
</p>
<p>
Note that although this is supported for convenience, this thwarts one
of the main reasons to use buffers, which is to avoid string
allocations. Rewrite it with <tt>buf:put()</tt> and <tt>buf:get()</tt>.
</p>
<p>
Mixing this with unrelated objects that have a <tt>__concat</tt>
metamethod may not work, since these probably only expect strings.
</p>
<h3 id="buffer_skip"><tt>buf = buf:skip(len)</tt></h3>
<p>
Skips (consumes) <tt>len</tt> bytes from the buffer up to the current
length of the buffer data.
</p>
<h3 id="buffer_get"><tt>str, … = buf:get([len|nil] [,…])</tt></h3>
<p>
Consumes the buffer data and returns one or more strings. If called
without arguments, the whole buffer data is consumed. If called with a
number, up to <tt>len</tt> bytes are consumed. A <tt>nil</tt> argument
consumes the remaining buffer space (this only makes sense as the last
argument). Multiple arguments consume the buffer data in the given
order.
</p>
<p>
Note: a zero length or no remaining buffer data returns an empty string
and not <tt>nil</tt>.
</p>
<h3 id="buffer_tostring"><tt>str = buf:tostring()<br>
str = tostring(buf)</tt></h3>
<p>
Creates a string from the buffer data, but doesn't consume it. The
buffer remains unchanged.
</p>
<p>
Buffer objects also define a <tt>__tostring</tt> metamethod. This means
buffers can be passed to the global <tt>tostring()</tt> function and
many other functions that accept this in place of strings. The important
internal uses in functions like <tt>io.write()</tt> are short-circuited
to avoid the creation of an intermediate string object.
</p>
<h3 id="buffer_ref"><tt>ptr, len = buf:ref()</tt><span class="lib">FFI</span></h3>
<p>
Returns an <tt>uint8_t&nbsp;*</tt> FFI cdata pointer <tt>ptr</tt> that
points to the buffer data. The length of the buffer data in bytes is
returned in <tt>len</tt>.
</p>
<p>
The returned pointer can be directly passed to C functions that expect a
buffer and a length. You can also do bytewise reads
(<tt>local&nbsp;x&nbsp;=&nbsp;ptr[i]</tt>) or writes
(<tt>ptr[i]&nbsp;=&nbsp;0x40</tt>) of the buffer data.
</p>
<p>
In conjunction with the <tt>skip</tt> method, this allows zero-copy use
of C write-style APIs:
</p>
<pre class="code">
repeat
local ptr, len = buf:ref()
if len == 0 then break end
local n = C.write(fd, ptr, len)
if n &lt; 0 then error("write error") end
buf:skip(n)
until n >= len
</pre>
<p>
Unlike Lua strings, buffer data is <i>not</i> implicitly
zero-terminated. It's not safe to pass <tt>ptr</tt> to C functions that
expect zero-terminated strings. If you're not using <tt>len</tt>, then
you're doing something wrong.
</p>
<h2 id="serialize">Serialization of Lua Objects</h2>
<p>
The following functions and methods allow <b>high-speed serialization</b>
(encoding) of a Lua object into a string and decoding it back to a Lua
object. This allows convenient storage and transport of <b>structured
data</b>.
</p>
<p>
The encoded data is in an <a href="#serialize_format">internal binary
format</a>. The data can be stored in files, binary-transparent
databases or transmitted to other LuaJIT instances across threads,
processes or networks.
</p>
<p>
Encoding speed can reach up to 1 Gigabyte/second on a modern desktop- or
server-class system, even when serializing many small objects. Decoding
speed is mostly constrained by object creation cost.
</p>
<p>
The serializer handles most Lua types, common FFI number types and
nested structures. Functions, thread objects, other FFI cdata and full
userdata cannot be serialized (yet).
</p>
<p>
The encoder serializes nested structures as trees. Multiple references
to a single object will be stored separately and create distinct objects
after decoding. Circular references cause an error.
</p>
<h3 id="serialize_methods">Serialization Functions and Methods</h3>
<h3 id="buffer_encode"><tt>str = buffer.encode(obj)<br>
buf = buf:encode(obj)</tt></h3>
<p>
Serializes (encodes) the Lua object <tt>obj</tt>. The stand-alone
function returns a string <tt>str</tt>. The buffer method appends the
encoding to the buffer.
</p>
<p>
<tt>obj</tt> can be any of the supported Lua types &mdash; it doesn't
need to be a Lua table.
</p>
<p>
This function may throw an error when attempting to serialize
unsupported object types, circular references or deeply nested tables.
</p>
<h3 id="buffer_decode"><tt>obj = buffer.decode(str)<br>
obj = buf:decode()</tt></h3>
<p>
The stand-alone function deserializes (decodes) the string
<tt>str</tt>, the buffer method deserializes one object from the
buffer. Both return a Lua object <tt>obj</tt>.
</p>
<p>
The returned object may be any of the supported Lua types &mdash;
even <tt>nil</tt>.
</p>
<p>
This function may throw an error when fed with malformed or incomplete
encoded data. The stand-alone function throws when there's left-over
data after decoding a single top-level object. The buffer method leaves
any left-over data in the buffer.
</p>
<p>
Attempting to deserialize an FFI type will throw an error, if the FFI
library is not built-in or has not been loaded, yet.
</p>
<h3 id="serialize_options">Serialization Options</h3>
<p>
The <tt>options</tt> table passed to <tt>buffer.new()</tt> may contain
the following members (all optional):
</p>
<ul>
<li>
<tt>dict</tt> is a Lua table holding a <b>dictionary of strings</b> that
commonly occur as table keys of objects you are serializing. These keys
are compactly encoded as indexes during serialization. A well-chosen
dictionary saves space and improves serialization performance.
</li>
<li>
<tt>metatable</tt> is a Lua table holding a <b>dictionary of metatables</b>
for the table objects you are serializing.
</li>
</ul>
<p>
<tt>dict</tt> needs to be an array of strings and <tt>metatable</tt> needs
to be an array of tables. Both starting at index 1 and without holes (no
<tt>nil</tt> in between). The tables are anchored in the buffer object and
internally modified into a two-way index (don't do this yourself, just pass
a plain array). The tables must not be modified after they have been passed
to <tt>buffer.new()</tt>.
</p>
<p>
The <tt>dict</tt> and <tt>metatable</tt> tables used by the encoder and
decoder must be the same. Put the most common entries at the front. Extend
at the end to ensure backwards-compatibility &mdash; older encodings can
then still be read. You may also set some indexes to <tt>false</tt> to
explicitly drop backwards-compatibility. Old encodings that use these
indexes will throw an error when decoded.
</p>
<p>
Metatables that are not found in the <tt>metatable</tt> dictionary are
ignored when encoding. Decoding returns a table with a <tt>nil</tt>
metatable.
</p>
<p>
Note: parsing and preparation of the options table is somewhat
expensive. Create a buffer object only once and recycle it for multiple
uses. Avoid mixing encoder and decoder buffers, since the
<tt>buf:set()</tt> method frees the already allocated buffer space:
</p>
<pre class="code">
local options = {
dict = { "commonly", "used", "string", "keys" },
}
local buf_enc = buffer.new(options)
local buf_dec = buffer.new(options)
local function encode(obj)
return buf_enc:reset():encode(obj):get()
end
local function decode(str)
return buf_dec:set(str):decode()
end
</pre>
<h3 id="serialize_stream">Streaming Serialization</h3>
<p>
In some contexts, it's desirable to do piecewise serialization of large
datasets, also known as <i>streaming</i>.
</p>
<p>
This serialization format can be safely concatenated and supports streaming.
Multiple encodings can simply be appended to a buffer and later decoded
individually:
</p>
<pre class="code">
local buf = buffer.new()
buf:encode(obj1)
buf:encode(obj2)
local copy1 = buf:decode()
local copy2 = buf:decode()
</pre>
<p>
Here's how to iterate over a stream:
</p>
<pre class="code">
while #buf ~= 0 do
local obj = buf:decode()
-- Do something with obj.
end
</pre>
<p>
Since the serialization format doesn't prepend a length to its encoding,
network applications may need to transmit the length, too.
</p>
<h3 id="serialize_format">Serialization Format Specification</h3>
<p>
This serialization format is designed for <b>internal use</b> by LuaJIT
applications. Serialized data is upwards-compatible and portable across
all supported LuaJIT platforms.
</p>
<p>
It's an <b>8-bit binary format</b> and not human-readable. It uses e.g.
embedded zeroes and stores embedded Lua string objects unmodified, which
are 8-bit-clean, too. Encoded data can be safely concatenated for
streaming and later decoded one top-level object at a time.
</p>
<p>
The encoding is reasonably compact, but tuned for maximum performance,
not for minimum space usage. It compresses well with any of the common
byte-oriented data compression algorithms.
</p>
<p>
Although documented here for reference, this format is explicitly
<b>not</b> intended to be a 'public standard' for structured data
interchange across computer languages (like JSON or MessagePack). Please
do not use it as such.
</p>
<p>
The specification is given below as a context-free grammar with a
top-level <tt>object</tt> as the starting point. Alternatives are
separated by the <tt>|</tt> symbol and <tt>*</tt> indicates repeats.
Grouping is implicit or indicated by <tt>{…}</tt>. Terminals are
either plain hex numbers, encoded as bytes, or have a <tt>.format</tt>
suffix.
</p>
<pre>
object → nil | false | true
| null | lightud32 | lightud64
| int | num | tab | tab_mt
| int64 | uint64 | complex
| string
nil → 0x00
false → 0x01
true → 0x02
null → 0x03 // NULL lightuserdata
lightud32 → 0x04 data.I // 32 bit lightuserdata
lightud64 → 0x05 data.L // 64 bit lightuserdata
int → 0x06 int.I // int32_t
num → 0x07 double.L
tab → 0x08 // Empty table
| 0x09 h.U h*{object object} // Key/value hash
| 0x0a a.U a*object // 0-based array
| 0x0b a.U h.U a*object h*{object object} // Mixed
| 0x0c a.U (a-1)*object // 1-based array
| 0x0d a.U h.U (a-1)*object h*{object object} // Mixed
tab_mt → 0x0e (index-1).U tab // Metatable dict entry
int64 → 0x10 int.L // FFI int64_t
uint64 → 0x11 uint.L // FFI uint64_t
complex → 0x12 re.L im.L // FFI complex
string → (0x20+len).U len*char.B
| 0x0f (index-1).U // String dict entry
.B = 8 bit
.I = 32 bit little-endian
.L = 64 bit little-endian
.U = prefix-encoded 32 bit unsigned number n:
0x00..0xdf → n.B
0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B
0x1fe0.. → 0xff n.I
</pre>
<h2 id="error">Error handling</h2>
<p>
Many of the buffer methods can throw an error. Out-of-memory or usage
errors are best caught with an outer wrapper for larger parts of code.
There's not much one can do after that, anyway.
</p>
<p>
OTOH, you may want to catch some errors individually. Buffer methods need
to receive the buffer object as the first argument. The Lua colon-syntax
<tt>obj:method()</tt> does that implicitly. But to wrap a method with
<tt>pcall()</tt>, the arguments need to be passed like this:
</p>
<pre class="code">
local ok, err = pcall(buf.encode, buf, obj)
if not ok then
-- Handle error in err.
end
</pre>
<h2 id="ffi_caveats">FFI caveats</h2>
<p>
The string buffer library has been designed to work well together with
the FFI library. But due to the low-level nature of the FFI library,
some care needs to be taken:
</p>
<p>
First, please remember that FFI pointers are zero-indexed. The space
returned by <tt>buf:reserve()</tt> and <tt>buf:ref()</tt> starts at the
returned pointer and ends before <tt>len</tt> bytes after that.
</p>
<p>
I.e. the first valid index is <tt>ptr[0]</tt> and the last valid index
is <tt>ptr[len-1]</tt>. If the returned length is zero, there's no valid
index at all. The returned pointer may even be <tt>NULL</tt>.
</p>
<p>
The space pointed to by the returned pointer is only valid as long as
the buffer is not modified in any way (neither append, nor consume, nor
reset, etc.). The pointer is also not a GC anchor for the buffer object
itself.
</p>
<p>
Buffer data is only guaranteed to be byte-aligned. Casting the returned
pointer to a data type with higher alignment may cause unaligned
accesses. It depends on the CPU architecture whether this is allowed or
not (it's always OK on x86/x64 and mostly OK on other modern
architectures).
</p>
<p>
FFI pointers or references do not count as GC anchors for an underlying
object. E.g. an <tt>array</tt> allocated with <tt>ffi.new()</tt> is
anchored by <tt>buf:set(array,&nbsp;len)</tt>, but not by
<tt>buf:set(array+offset,&nbsp;len)</tt>. The addition of the offset
creates a new pointer, even when the offset is zero. In this case, you
need to make sure there's still a reference to the original array as
long as its contents are in use by the buffer.
</p>
<p>
Even though each LuaJIT VM instance is single-threaded (but you can
create multiple VMs), FFI data structures can be accessed concurrently.
Be careful when reading/writing FFI cdata from/to buffers to avoid
concurrent accesses or modifications. In particular, the memory
referenced by <tt>buf:set(cdata,&nbsp;len)</tt> must not be modified
while buffer readers are working on it. Shared, but read-only memory
mappings of files are OK, but only if the file does not change.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

View File

@ -1,183 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Lua/C API Extensions</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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>Lua/C API Extensions</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 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 class="current" href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
LuaJIT adds some extensions to the standard Lua/C API. The LuaJIT include
directory must be in the compiler search path (<tt>-I<i>path</i></tt>)
to be able to include the required header for C code:
</p>
<pre class="code">
#include "luajit.h"
</pre>
<p>
Or for C++ code:
</p>
<pre class="code">
#include "lua.hpp"
</pre>
<h2 id="luaJIT_setmode"><tt>luaJIT_setmode(L, idx, mode)</tt>
&mdash; Control VM</h2>
<p>
This is a C API extension to allow control of the VM from C code. The
full prototype of <tt>LuaJIT_setmode</tt> is:
</p>
<pre class="code">
LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
</pre>
<p>
The returned status is either success (<tt>1</tt>) or failure (<tt>0</tt>).
The second argument is either <tt>0</tt> or a stack index (similar to the
other Lua/C API functions).
</p>
<p>
The third argument specifies the mode, which is 'or'ed with a flag.
The flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature off,
<tt>LUAJIT_MODE_ON</tt> to turn a feature on, or
<tt>LUAJIT_MODE_FLUSH</tt> to flush cached code.
</p>
<p>
The following modes are defined:
</p>
<h3 id="mode_engine"><tt>luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)</tt></h3>
<p>
Turn the whole JIT compiler on or off or flush the whole cache of compiled code.
</p>
<h3 id="mode_func"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)</tt><br>
<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)</tt><br>
<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)</tt></h3>
<p>
This sets the mode for the function at the stack index <tt>idx</tt> or
the parent of the calling function (<tt>idx = 0</tt>). It either
enables JIT compilation for a function, disables it and flushes any
already compiled code, or only flushes already compiled code. This
applies recursively to all sub-functions of the function with
<tt>LUAJIT_MODE_ALLFUNC</tt> or only to the sub-functions with
<tt>LUAJIT_MODE_ALLSUBFUNC</tt>.
</p>
<h3 id="mode_trace"><tt>luaJIT_setmode(L, trace,<br>
&nbsp;&nbsp;LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)</tt></h3>
<p>
Flushes the specified root trace and all of its side traces from the cache.
The code for the trace will be retained as long as there are any other
traces which link to it.
</p>
<h3 id="mode_wrapcfunc"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)</tt></h3>
<p>
This mode defines a wrapper function for calls to C functions. If
called with <tt>LUAJIT_MODE_ON</tt>, the stack index at <tt>idx</tt>
must be a <tt>lightuserdata</tt> object holding a pointer to the wrapper
function. From now on, all C functions are called through the wrapper
function. If called with <tt>LUAJIT_MODE_OFF</tt> this mode is turned
off and all C functions are directly called.
</p>
<p>
The wrapper function can be used for debugging purposes or to catch
and convert foreign exceptions. But please read the section on
<a href="extensions.html#exceptions">C++&nbsp;exception interoperability</a>
first. Recommended usage can be seen in this C++ code excerpt:
</p>
<pre class="code">
#include &lt;exception&gt;
#include "lua.hpp"
// Catch C++ exceptions and convert them to Lua error messages.
// Customize as needed for your own exception classes.
static int wrap_exceptions(lua_State *L, lua_CFunction f)
{
try {
return f(L); // Call wrapped function and return result.
} catch (const char *s) { // Catch and convert exceptions.
lua_pushstring(L, s);
} catch (std::exception& e) {
lua_pushstring(L, e.what());
} catch (...) {
lua_pushliteral(L, "caught (...)");
}
return lua_error(L); // Rethrow as a Lua error.
}
static int myinit(lua_State *L)
{
...
// Define wrapper function and enable it.
lua_pushlightuserdata(L, (void *)wrap_exceptions);
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
lua_pop(L, 1);
...
}
</pre>
<p>
Note that you can only define <b>a single global wrapper function</b>,
so be careful when using this mechanism from multiple C++ modules.
Also note that this mechanism is not without overhead.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

View File

@ -1,326 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>FFI Library</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

View File

@ -1,568 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>ffi.* API Functions</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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">
table.abitable { width: 30em; line-height: 1.2; }
tr.abihead td { font-weight: bold; }
td.abiparam { font-weight: bold; width: 6em; }
</style>
</head>
<body>
<div id="site">
<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1><tt>ffi.*</tt> API Functions</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 href="ext_ffi.html">FFI Library</a>
<ul><li>
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
</li><li>
<a class="current" 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
This page describes the API functions provided by the FFI library in
detail. It's recommended to read through the
<a href="ext_ffi.html">introduction</a> and the
<a href="ext_ffi_tutorial.html">FFI tutorial</a> first.
</p>
<h2 id="glossary">Glossary</h2>
<ul>
<li><b>cdecl</b> &mdash; An abstract C&nbsp;type declaration (a Lua
string).</li>
<li><b>ctype</b> &mdash; A C&nbsp;type object. This is a special kind of
<b>cdata</b> returned by <tt>ffi.typeof()</tt>. It serves as a
<b>cdata</b> <a href="#ffi_new">constructor</a> when called.</li>
<li><b>cdata</b> &mdash; A C&nbsp;data object. It holds a value of the
corresponding <b>ctype</b>.</li>
<li><b>ct</b> &mdash; A C&nbsp;type specification which can be used for
most of the API functions. Either a <b>cdecl</b>, a <b>ctype</b> or a
<b>cdata</b> serving as a template type.</li>
<li><b>cb</b> &mdash; A callback object. This is a C&nbsp;data object
holding a special function pointer. Calling this function from
C&nbsp;code runs an associated Lua function.</li>
<li><b>VLA</b> &mdash; A variable-length array is declared with a
<tt>?</tt> instead of the number of elements, e.g. <tt>"int[?]"</tt>.
The number of elements (<tt>nelem</tt>) must be given when it's
<a href="#ffi_new">created</a>.</li>
<li><b>VLS</b> &mdash; A variable-length struct is a <tt>struct</tt> C
type where the last element is a <b>VLA</b>. The same rules for
declaration and creation apply.</li>
</ul>
<h2 id="decl">Declaring and Accessing External Symbols</h2>
<p>
External symbols must be declared first and can then be accessed by
indexing a <a href="ext_ffi_semantics.html#clib">C&nbsp;library
namespace</a>, which automatically binds the symbol to a specific
library.
</p>
<h3 id="ffi_cdef"><tt>ffi.cdef(def)</tt></h3>
<p>
Adds multiple C&nbsp;declarations for types or external symbols (named
variables or functions). <tt>def</tt> must be a Lua string. It's
recommended to use the syntactic sugar for string arguments as
follows:
</p>
<pre class="code">
ffi.cdef[[
<span style="color:#00a000;">typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
int dofoo(foo_t *f, int n); /* Declare an external C function. */</span>
]]
</pre>
<p>
The contents of the string (the part in green above) must be a
sequence of
<a href="ext_ffi_semantics.html#clang">C&nbsp;declarations</a>,
separated by semicolons. The trailing semicolon for a single
declaration may be omitted.
</p>
<p>
Please note, that external symbols are only <em>declared</em>, but they
are <em>not bound</em> to any specific address, yet. Binding is
achieved with C&nbsp;library namespaces (see below).
</p>
<p style="color: #c00000;">
C&nbsp;declarations are not passed through a C&nbsp;pre-processor,
yet. No pre-processor tokens are allowed, except for
<tt>#pragma&nbsp;pack</tt>. Replace <tt>#define</tt> in existing
C&nbsp;header files with <tt>enum</tt>, <tt>static&nbsp;const</tt>
or <tt>typedef</tt> and/or pass the files through an external
C&nbsp;pre-processor (once). Be careful not to include unneeded or
redundant declarations from unrelated header files.
</p>
<h3 id="ffi_C"><tt>ffi.C</tt></h3>
<p>
This is the default C&nbsp;library namespace &mdash; note the
uppercase <tt>'C'</tt>. It binds to the default set of symbols or
libraries on the target system. These are more or less the same as a
C&nbsp;compiler would offer by default, without specifying extra link
libraries.
</p>
<p>
On POSIX systems, this binds to symbols in the default or global
namespace. This includes all exported symbols from the executable and
any libraries loaded into the global namespace. This includes at least
<tt>libc</tt>, <tt>libm</tt>, <tt>libdl</tt> (on Linux),
<tt>libgcc</tt> (if compiled with GCC), as well as any exported
symbols from the Lua/C&nbsp;API provided by LuaJIT itself.
</p>
<p>
On Windows systems, this binds to symbols exported from the
<tt>*.exe</tt>, the <tt>lua51.dll</tt> (i.e. the Lua/C&nbsp;API
provided by LuaJIT itself), the C&nbsp;runtime library LuaJIT was linked
with (<tt>msvcrt*.dll</tt>), <tt>kernel32.dll</tt>,
<tt>user32.dll</tt> and <tt>gdi32.dll</tt>.
</p>
<h3 id="ffi_load"><tt>clib = ffi.load(name [,global])</tt></h3>
<p>
This loads the dynamic library given by <tt>name</tt> and returns
a new C&nbsp;library namespace which binds to its symbols. On POSIX
systems, if <tt>global</tt> is <tt>true</tt>, the library symbols are
loaded into the global namespace, too.
</p>
<p>
If <tt>name</tt> is a path, the library is loaded from this path.
Otherwise <tt>name</tt> is canonicalized in a system-dependent way and
searched in the default search path for dynamic libraries:
</p>
<p>
On POSIX systems, if the name contains no dot, the extension
<tt>.so</tt> is appended. Also, the <tt>lib</tt> prefix is prepended
if necessary. So <tt>ffi.load("z")</tt> looks for <tt>"libz.so"</tt>
in the default shared library search path.
</p>
<p>
On Windows systems, if the name contains no dot, the extension
<tt>.dll</tt> is appended. So <tt>ffi.load("ws2_32")</tt> looks for
<tt>"ws2_32.dll"</tt> in the default DLL search path.
</p>
<h2 id="create">Creating cdata Objects</h2>
<p>
The following API functions create cdata objects (<tt>type()</tt>
returns <tt>"cdata"</tt>). All created cdata objects are
<a href="ext_ffi_semantics.html#gc">garbage collected</a>.
</p>
<h3 id="ffi_new"><tt>cdata = ffi.new(ct [,nelem] [,init...])<br>
cdata = <em>ctype</em>([nelem,] [init...])</tt></h3>
<p>
Creates a cdata object for the given <tt>ct</tt>. VLA/VLS types
require the <tt>nelem</tt> argument. The second syntax uses a ctype as
a constructor and is otherwise fully equivalent.
</p>
<p>
The cdata object is initialized according to the
<a href="ext_ffi_semantics.html#init">rules for initializers</a>,
using the optional <tt>init</tt> arguments. Excess initializers cause
an error.
</p>
<p>
Performance notice: if you want to create many objects of one kind,
parse the cdecl only once and get its ctype with
<tt>ffi.typeof()</tt>. Then use the ctype as a constructor repeatedly.
</p>
<p style="font-size: 8pt;">
Please note, that an anonymous <tt>struct</tt> declaration implicitly
creates a new and distinguished ctype every time you use it for
<tt>ffi.new()</tt>. This is probably <b>not</b> what you want,
especially if you create more than one cdata object. Different anonymous
<tt>structs</tt> are not considered assignment-compatible by the
C&nbsp;standard, even though they may have the same fields! Also, they
are considered different types by the JIT-compiler, which may cause an
excessive number of traces. It's strongly suggested to either declare
a named <tt>struct</tt> or <tt>typedef</tt> with <tt>ffi.cdef()</tt>
or to create a single ctype object for an anonymous <tt>struct</tt>
with <tt>ffi.typeof()</tt>.
</p>
<h3 id="ffi_typeof"><tt>ctype = ffi.typeof(ct)</tt></h3>
<p>
Creates a ctype object for the given <tt>ct</tt>.
</p>
<p>
This function is especially useful to parse a cdecl only once and then
use the resulting ctype object as a <a href="#ffi_new">constructor</a>.
</p>
<h3 id="ffi_cast"><tt>cdata = ffi.cast(ct, init)</tt></h3>
<p>
Creates a scalar cdata object for the given <tt>ct</tt>. The cdata
object is initialized with <tt>init</tt> using the "cast" variant of
the <a href="ext_ffi_semantics.html#convert">C&nbsp;type conversion
rules</a>.
</p>
<p>
This functions is mainly useful to override the pointer compatibility
checks or to convert pointers to addresses or vice versa.
</p>
<h3 id="ffi_metatype"><tt>ctype = ffi.metatype(ct, metatable)</tt></h3>
<p>
Creates a ctype object for the given <tt>ct</tt> and associates it with
a metatable. Only <tt>struct</tt>/<tt>union</tt> types, complex numbers
and vectors are allowed. Other types may be wrapped in a
<tt>struct</tt>, if needed.
</p>
<p>
The association with a metatable is permanent and cannot be changed
afterwards. Neither the contents of the <tt>metatable</tt> nor the
contents of an <tt>__index</tt> table (if any) may be modified
afterwards. The associated metatable automatically applies to all uses
of this type, no matter how the objects are created or where they
originate from. Note that predefined operations on types have
precedence (e.g. declared field names cannot be overridden).
</p>
<p>
All standard Lua metamethods are implemented. These are called directly,
without shortcuts, and on any mix of types. For binary operations, the
left operand is checked first for a valid ctype metamethod. The
<tt>__gc</tt> metamethod only applies to <tt>struct</tt>/<tt>union</tt>
types and performs an implicit <a href="#ffi_gc"><tt>ffi.gc()</tt></a>
call during creation of an instance.
</p>
<h3 id="ffi_gc"><tt>cdata = ffi.gc(cdata, finalizer)</tt></h3>
<p>
Associates a finalizer with a pointer or aggregate cdata object. The
cdata object is returned unchanged.
</p>
<p>
This function allows safe integration of unmanaged resources into the
automatic memory management of the LuaJIT garbage collector. Typical
usage:
</p>
<pre class="code">
local p = ffi.gc(ffi.C.malloc(n), ffi.C.free)
...
p = nil -- Last reference to p is gone.
-- GC will eventually run finalizer: ffi.C.free(p)
</pre>
<p>
A cdata finalizer works like the <tt>__gc</tt> metamethod for userdata
objects: when the last reference to a cdata object is gone, the
associated finalizer is called with the cdata object as an argument. The
finalizer can be a Lua function or a cdata function or cdata function
pointer. An existing finalizer can be removed by setting a <tt>nil</tt>
finalizer, e.g. right before explicitly deleting a resource:
</p>
<pre class="code">
ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.
</pre>
<h2 id="info">C&nbsp;Type Information</h2>
<p>
The following API functions return information about C&nbsp;types.
They are most useful for inspecting cdata objects.
</p>
<h3 id="ffi_sizeof"><tt>size = ffi.sizeof(ct [,nelem])</tt></h3>
<p>
Returns the size of <tt>ct</tt> in bytes. Returns <tt>nil</tt> if
the size is not known (e.g. for <tt>"void"</tt> or function types).
Requires <tt>nelem</tt> for VLA/VLS types, except for cdata objects.
</p>
<h3 id="ffi_alignof"><tt>align = ffi.alignof(ct)</tt></h3>
<p>
Returns the minimum required alignment for <tt>ct</tt> in bytes.
</p>
<h3 id="ffi_offsetof"><tt>ofs [,bpos,bsize] = ffi.offsetof(ct, field)</tt></h3>
<p>
Returns the offset (in bytes) of <tt>field</tt> relative to the start
of <tt>ct</tt>, which must be a <tt>struct</tt>. Additionally returns
the position and the field size (in bits) for bit fields.
</p>
<h3 id="ffi_istype"><tt>status = ffi.istype(ct, obj)</tt></h3>
<p>
Returns <tt>true</tt> if <tt>obj</tt> has the C&nbsp;type given by
<tt>ct</tt>. Returns <tt>false</tt> otherwise.
</p>
<p>
C&nbsp;type qualifiers (<tt>const</tt> etc.) are ignored. Pointers are
checked with the standard pointer compatibility rules, but without any
special treatment for <tt>void&nbsp;*</tt>. If <tt>ct</tt> specifies a
<tt>struct</tt>/<tt>union</tt>, then a pointer to this type is accepted,
too. Otherwise the types must match exactly.
</p>
<p>
Note: this function accepts all kinds of Lua objects for the
<tt>obj</tt> argument, but always returns <tt>false</tt> for non-cdata
objects.
</p>
<h2 id="util">Utility Functions</h2>
<h3 id="ffi_errno"><tt>err = ffi.errno([newerr])</tt></h3>
<p>
Returns the error number set by the last C&nbsp;function call which
indicated an error condition. If the optional <tt>newerr</tt> argument
is present, the error number is set to the new value and the previous
value is returned.
</p>
<p>
This function offers a portable and OS-independent way to get and set the
error number. Note that only <em>some</em> C&nbsp;functions set the error
number. And it's only significant if the function actually indicated an
error condition (e.g. with a return value of <tt>-1</tt> or
<tt>NULL</tt>). Otherwise, it may or may not contain any previously set
value.
</p>
<p>
You're advised to call this function only when needed and as close as
possible after the return of the related C&nbsp;function. The
<tt>errno</tt> value is preserved across hooks, memory allocations,
invocations of the JIT compiler and other internal VM activity. The same
applies to the value returned by <tt>GetLastError()</tt> on Windows, but
you need to declare and call it yourself.
</p>
<h3 id="ffi_string"><tt>str = ffi.string(ptr [,len])</tt></h3>
<p>
Creates an interned Lua string from the data pointed to by
<tt>ptr</tt>.
</p>
<p>
If the optional argument <tt>len</tt> is missing, <tt>ptr</tt> is
converted to a <tt>"char&nbsp;*"</tt> and the data is assumed to be
zero-terminated. The length of the string is computed with
<tt>strlen()</tt>.
</p>
<p>
Otherwise <tt>ptr</tt> is converted to a <tt>"void&nbsp;*"</tt> and
<tt>len</tt> gives the length of the data. The data may contain
embedded zeros and need not be byte-oriented (though this may cause
endianess issues).
</p>
<p>
This function is mainly useful to convert (temporary)
<tt>"const&nbsp;char&nbsp;*"</tt> pointers returned by
C&nbsp;functions to Lua strings and store them or pass them to other
functions expecting a Lua string. The Lua string is an (interned) copy
of the data and bears no relation to the original data area anymore.
Lua strings are 8&nbsp;bit clean and may be used to hold arbitrary,
non-character data.
</p>
<p>
Performance notice: it's faster to pass the length of the string, if
it's known. E.g. when the length is returned by a C&nbsp;call like
<tt>sprintf()</tt>.
</p>
<h3 id="ffi_copy"><tt>ffi.copy(dst, src, len)<br>
ffi.copy(dst, str)</tt></h3>
<p>
Copies the data pointed to by <tt>src</tt> to <tt>dst</tt>.
<tt>dst</tt> is converted to a <tt>"void&nbsp;*"</tt> and <tt>src</tt>
is converted to a <tt>"const void&nbsp;*"</tt>.
</p>
<p>
In the first syntax, <tt>len</tt> gives the number of bytes to copy.
Caveat: if <tt>src</tt> is a Lua string, then <tt>len</tt> must not
exceed <tt>#src+1</tt>.
</p>
<p>
In the second syntax, the source of the copy must be a Lua string. All
bytes of the string <em>plus a zero-terminator</em> are copied to
<tt>dst</tt> (i.e. <tt>#src+1</tt> bytes).
</p>
<p>
Performance notice: <tt>ffi.copy()</tt> may be used as a faster
(inlinable) replacement for the C&nbsp;library functions
<tt>memcpy()</tt>, <tt>strcpy()</tt> and <tt>strncpy()</tt>.
</p>
<h3 id="ffi_fill"><tt>ffi.fill(dst, len [,c])</tt></h3>
<p>
Fills the data pointed to by <tt>dst</tt> with <tt>len</tt> constant
bytes, given by <tt>c</tt>. If <tt>c</tt> is omitted, the data is
zero-filled.
</p>
<p>
Performance notice: <tt>ffi.fill()</tt> may be used as a faster
(inlinable) replacement for the C&nbsp;library function
<tt>memset(dst,&nbsp;c,&nbsp;len)</tt>. Please note the different
order of arguments!
</p>
<h2 id="target">Target-specific Information</h2>
<h3 id="ffi_abi"><tt>status = ffi.abi(param)</tt></h3>
<p>
Returns <tt>true</tt> if <tt>param</tt> (a Lua string) applies for the
target ABI (Application Binary Interface). Returns <tt>false</tt>
otherwise. The following parameters are currently defined:
</p>
<table class="abitable">
<tr class="abihead">
<td class="abiparam">Parameter</td>
<td class="abidesc">Description</td>
</tr>
<tr class="odd separate">
<td class="abiparam">32bit</td><td class="abidesc">32 bit architecture</td></tr>
<tr class="even">
<td class="abiparam">64bit</td><td class="abidesc">64 bit architecture</td></tr>
<tr class="odd separate">
<td class="abiparam">le</td><td class="abidesc">Little-endian architecture</td></tr>
<tr class="even">
<td class="abiparam">be</td><td class="abidesc">Big-endian architecture</td></tr>
<tr class="odd separate">
<td class="abiparam">fpu</td><td class="abidesc">Target has a hardware FPU</td></tr>
<tr class="even">
<td class="abiparam">softfp</td><td class="abidesc">softfp calling conventions</td></tr>
<tr class="odd">
<td class="abiparam">hardfp</td><td class="abidesc">hardfp calling conventions</td></tr>
<tr class="even separate">
<td class="abiparam">eabi</td><td class="abidesc">EABI variant of the standard ABI</td></tr>
<tr class="odd">
<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
<tr class="even">
<td class="abiparam">pauth</td><td class="abidesc">Pointer authentication ABI</td></tr>
<tr class="odd">
<td class="abiparam">uwp</td><td class="abidesc">Universal Windows Platform</td></tr>
<tr class="even">
<td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr>
</table>
<h3 id="ffi_os"><tt>ffi.os</tt></h3>
<p>
Contains the target OS name. Same contents as
<a href="ext_jit.html#jit_os"><tt>jit.os</tt></a>.
</p>
<h3 id="ffi_arch"><tt>ffi.arch</tt></h3>
<p>
Contains the target architecture name. Same contents as
<a href="ext_jit.html#jit_arch"><tt>jit.arch</tt></a>.
</p>
<h2 id="callback">Methods for Callbacks</h2>
<p>
The C&nbsp;types for <a href="ext_ffi_semantics.html#callback">callbacks</a>
have some extra methods:
</p>
<h3 id="callback_free"><tt>cb:free()</tt></h3>
<p>
Free the resources associated with a callback. The associated Lua
function is unanchored and may be garbage collected. The callback
function pointer is no longer valid and must not be called again
(it may be reused by a subsequently created callback).
</p>
<h3 id="callback_set"><tt>cb:set(func)</tt></h3>
<p>
Associate a new Lua function with a callback. The C&nbsp;type of the
callback and the callback function pointer are unchanged.
</p>
<p>
This method is useful to dynamically switch the receiver of callbacks
without creating a new callback each time and registering it again (e.g.
with a GUI library).
</p>
<h2 id="extended">Extended Standard Library Functions</h2>
<p>
The following standard library functions have been extended to work
with cdata objects:
</p>
<h3 id="tonumber"><tt>n = tonumber(cdata)</tt></h3>
<p>
Converts a number cdata object to a <tt>double</tt> and returns it as
a Lua number. This is particularly useful for boxed 64&nbsp;bit
integer values. Caveat: this conversion may incur a precision loss.
</p>
<h3 id="tostring"><tt>s = tostring(cdata)</tt></h3>
<p>
Returns a string representation of the value of 64&nbsp;bit integers
(<tt><b>"</b>nnn<b>LL"</b></tt> or <tt><b>"</b>nnn<b>ULL"</b></tt>) or
complex numbers (<tt><b>"</b>re&plusmn;im<b>i"</b></tt>). Otherwise
returns a string representation of the C&nbsp;type of a ctype object
(<tt><b>"ctype&lt;</b>type<b>&gt;"</b></tt>) or a cdata object
(<tt><b>"cdata&lt;</b>type<b>&gt;:&nbsp;</b>address"</tt>), unless you
override it with a <tt>__tostring</tt> metamethod (see
<a href="#ffi_metatype"><tt>ffi.metatype()</tt></a>).
</p>
<h3 id="pairs"><tt>iter, obj, start = pairs(cdata)<br>
iter, obj, start = ipairs(cdata)<br></tt></h3>
<p>
Calls the <tt>__pairs</tt> or <tt>__ipairs</tt> metamethod of the
corresponding ctype.
</p>
<h2 id="literals">Extensions to the Lua Parser</h2>
<p>
The parser for Lua source code treats numeric literals with the
suffixes <tt>LL</tt> or <tt>ULL</tt> as signed or unsigned 64&nbsp;bit
integers. Case doesn't matter, but uppercase is recommended for
readability. It handles decimal (<tt>42LL</tt>), hexadecimal
(<tt>0x2aLL</tt>) and binary (<tt>0b101010LL</tt>) literals.
</p>
<p>
The imaginary part of complex numbers can be specified by suffixing
number literals with <tt>i</tt> or <tt>I</tt>, e.g. <tt>12.5i</tt>.
Caveat: you'll need to use <tt>1i</tt> to get an imaginary part with
the value one, since <tt>i</tt> itself still refers to a variable
named <tt>i</tt>.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,597 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>FFI Tutorial</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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">
table.idiomtable { font-size: 90%; line-height: 1.2; }
table.idiomtable tt { font-size: 100%; }
table.idiomtable td { vertical-align: top; }
tr.idiomhead td { font-weight: bold; }
td.idiomlua b { font-weight: normal; color: #2142bf; }
</style>
</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 Tutorial</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 href="ext_ffi.html">FFI Library</a>
<ul><li>
<a class="current" 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
This page is intended to give you an overview of the features of the FFI
library by presenting a few use cases and guidelines.
</p>
<p>
This page makes no attempt to explain all of the FFI library, though.
You'll want to have a look at the <a href="ext_ffi_api.html">ffi.* API
function reference</a> and the <a href="ext_ffi_semantics.html">FFI
semantics</a> to learn more.
</p>
<h2 id="load">Loading the FFI Library</h2>
<p>
The FFI library is built into LuaJIT by default, but it's not loaded
and initialized by default. The suggested way to use the FFI library
is to add the following to the start of every Lua file that needs one
of its functions:
</p>
<pre class="code">
local ffi = require("ffi")
</pre>
<p>
Please note, this doesn't define an <tt>ffi</tt> variable in the table
of globals &mdash; you really need to use the local variable. The
<tt>require</tt> function ensures the library is only loaded once.
</p>
<p style="font-size: 8pt;">
Note: If you want to experiment with the FFI from the interactive prompt
of the command line executable, omit the <tt>local</tt>, as it doesn't
preserve local variables across lines.
</p>
<h2 id="sleep">Accessing Standard System Functions</h2>
<p>
The following code explains how to access standard system functions.
We slowly print two lines of dots by sleeping for 10&nbsp;milliseconds
after each dot:
</p>
<pre class="code mark">
<span class="codemark">&nbsp;
&#9312;
&#9313;
&#9314;
&#9315;
&#9316;
&#9317;</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
function sleep(s)
ffi.C.Sleep(s*1000)
end
else
function sleep(s)
ffi.C.poll(nil, 0, s*1000)
end
end
for i=1,160 do
io.write("."); io.flush()
sleep(0.01)
end
io.write("\n")
</pre>
<p>
Here's the step-by-step explanation:
</p>
<p>
<span class="mark">&#9312;</span> This defines the
C&nbsp;library functions we're going to use. The part inside the
double-brackets (in green) is just standard C&nbsp;syntax. You can
usually get this info from the C&nbsp;header files or the
documentation provided by each C&nbsp;library or C&nbsp;compiler.
</p>
<p>
<span class="mark">&#9313;</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
with no clear consensus. Thankfully <tt>poll()</tt> can be used for
this task, too, and it's present on most non-Windows systems. The
check for <tt>ffi.os</tt> makes sure we use the Windows-specific
function only on Windows systems.
</p>
<p>
<span class="mark">&#9314;</span> Here we're wrapping the
call to the C&nbsp;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 class="mark">&#9315;</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
leaves it a Lua number, which is a floating-point value. Alas, the
<tt>Sleep()</tt> function only accepts an integer value. Luckily for
us, the FFI library automatically performs the conversion when calling
the function (truncating the FP value towards zero, like in C).
</p>
<p style="font-size: 8pt;">
Some readers will notice that <tt>Sleep()</tt> is part of
<tt>KERNEL32.DLL</tt> and is also a <tt>stdcall</tt> function. So how
can this possibly work? The FFI library provides the <tt>ffi.C</tt>
default C&nbsp;library namespace, which allows calling functions from
the default set of libraries, like a C&nbsp;compiler would. Also, the
FFI library automatically detects <tt>stdcall</tt> functions, so you
don't need to declare them as such.
</p>
<p>
<span class="mark">&#9316;</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
number&nbsp;<tt>0</tt> <em>does not convert to a pointer value</em>,
unlike in C++. You really have to pass pointers to pointer arguments
and numbers to number arguments.
</p>
<p style="font-size: 8pt;">
The page on <a href="ext_ffi_semantics.html">FFI semantics</a> has all
of the gory details about
<a href="ext_ffi_semantics.html#convert">conversions between Lua
objects and C&nbsp;types</a>. For the most part you don't have to deal
with this, as it's performed automatically and it's carefully designed
to bridge the semantic differences between Lua and C.
</p>
<p>
<span class="mark">&#9317;</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.
:-)
</p>
<h2 id="zlib">Accessing the zlib Compression Library</h2>
<p>
The following code shows how to access the <a
href="https://zlib.net/"><span class="ext">&raquo;</span>&nbsp;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 mark">
<span class="codemark">&nbsp;
&#9312;
&#9313;
&#9314;
&#9315;
&#9316;
&#9317;
&#9318;</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")
local function compress(txt)
local n = zlib.compressBound(#txt)
local buf = ffi.new("uint8_t[?]", n)
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])
end
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)
assert(res == 0)
return ffi.string(buf, buflen[0])
end
-- Simple test code.
local txt = string.rep("abcd", 1000)
print("Uncompressed size: ", #txt)
local c = compress(txt)
print("Compressed size: ", #c)
local txt2 = uncompress(c, #txt)
assert(txt2 == txt)
</pre>
<p>
Here's the step-by-step explanation:
</p>
<p>
<span class="mark">&#9312;</span> This defines some of the
C&nbsp;functions provided by zlib. For the sake of this example, some
type indirections have been reduced and it uses the predefined
fixed-size integer types, while still adhering to the zlib API/ABI.
</p>
<p>
<span class="mark">&#9313;</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
<tt>"z"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and
you'll have to download it first from the
<a href="https://zlib.net/"><span class="ext">&raquo;</span>&nbsp;zlib site</a>. The check for
<tt>ffi.os</tt> makes sure we pass the right name to
<tt>ffi.load()</tt>.
</p>
<p>
<span class="mark">&#9314;</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
size. The <tt>[?]</tt> in the type specification indicates a
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 class="mark">&#9315;</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
actual length that was used.
</p>
<p>
In C you'd pass in the address of a local variable
(<tt>&amp;buflen</tt>). But since there's no address-of operator in
Lua, we'll just pass in a one-element array. Conveniently, it can be
initialized with the maximum buffer size in one step. Calling the
actual <tt>zlib.compress2</tt> function is then straightforward.
</p>
<p>
<span class="mark">&#9316;</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
get it from there.
</p>
<p style="font-size: 8pt;">
Note that since the function returns now, the <tt>buf</tt> and
<tt>buflen</tt> variables will eventually be garbage collected. This
is fine, because <tt>ffi.string()</tt> has copied the contents to a
newly created (interned) Lua string. If you plan to call this function
lots of times, consider reusing the buffers and/or handing back the
results in buffers instead of strings. This will reduce the overhead
for garbage collection and string interning.
</p>
<p>
<span class="mark">&#9317;</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 class="mark">&#9318;</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 &mdash; the convenience
wrapper functions completely hide it.
</p>
<p>
One major advantage of the LuaJIT FFI is that you are now able to
write those wrappers <em>in Lua</em>. And at a fraction of the time it
would cost you to create an extra C&nbsp;module using the Lua/C API.
Many of the simpler C&nbsp;functions can probably be used directly
from your Lua code, without any wrappers.
</p>
<p style="font-size: 8pt;">
Side note: the zlib API uses the <tt>long</tt> type for passing
lengths and sizes around. But all those zlib functions actually only
deal with 32&nbsp;bit values. This is an unfortunate choice for a
public API, but may be explained by zlib's history &mdash; we'll just
have to deal with it.
</p>
<p style="font-size: 8pt;">
First, you should know that a <tt>long</tt> is a 64&nbsp;bit type e.g.
on POSIX/x64 systems, but a 32&nbsp;bit type on Windows/x64 and on
32&nbsp;bit systems. Thus a <tt>long</tt> result can be either a plain
Lua number or a boxed 64&nbsp;bit integer cdata object, depending on
the target system.
</p>
<p style="font-size: 8pt;">
Ok, so the <tt>ffi.*</tt> functions generally accept cdata objects
wherever you'd want to use a number. That's why we get a away with
passing <tt>n</tt> to <tt>ffi.string()</tt> above. But other Lua
library functions or modules don't know how to deal with this. So for
maximum portability, one needs to use <tt>tonumber()</tt> on returned
<tt>long</tt> results before passing them on. Otherwise the
application might work on some systems, but would fail in a POSIX/x64
environment.
</p>
<h2 id="metatype">Defining Metamethods for a C&nbsp;Type</h2>
<p>
The following code explains how to define metamethods for a C type.
We define a simple point type and add some operations to it:
</p>
<pre class="code mark">
<span class="codemark">&nbsp;
&#9312;
&#9313;
&#9314;
&#9315;
&#9316;
&#9317;</span>local ffi = require("ffi")
ffi.cdef[[
<span style="color:#00a000;">typedef struct { double x, y; } point_t;</span>
]]
local point
local mt = {
__add = function(a, b) return point(a.x+b.x, a.y+b.y) end,
__len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
__index = {
area = function(a) return a.x*a.x + a.y*a.y end,
},
}
point = ffi.metatype("point_t", mt)
local a = point(3, 4)
print(a.x, a.y) --> 3 4
print(#a) --> 5
print(a:area()) --> 25
local b = a + point(0.5, 8)
print(#b) --> 12.5
</pre>
<p>
Here's the step-by-step explanation:
</p>
<p>
<span class="mark">&#9312;</span> This defines the C&nbsp;type for a
two-dimensional point object.
</p>
<p>
<span class="mark">&#9313;</span> We have to declare the variable
holding the point constructor first, because it's used inside of a
metamethod.
</p>
<p>
<span class="mark">&#9314;</span> Let's define an <tt>__add</tt>
metamethod which adds the coordinates of two points and creates a new
point object. For simplicity, this function assumes that both arguments
are points. But it could be any mix of objects, if at least one operand
is of the required type (e.g. adding a point plus a number or vice
versa). Our <tt>__len</tt> metamethod returns the distance of a point to
the origin.
</p>
<p>
<span class="mark">&#9315;</span> If we run out of operators, we can
define named methods, too. Here, the <tt>__index</tt> table defines an
<tt>area</tt> function. For custom indexing needs, one might want to
define <tt>__index</tt> and <tt>__newindex</tt> <em>functions</em> instead.
</p>
<p>
<span class="mark">&#9316;</span> This associates the metamethods with
our C&nbsp;type. This only needs to be done once. For convenience, a
constructor is returned by
<a href="ext_ffi_api.html#ffi_metatype"><tt>ffi.metatype()</tt></a>.
We're not required to use it, though. The original C&nbsp;type can still
be used e.g. to create an array of points. The metamethods automatically
apply to any and all uses of this type.
</p>
<p>
Please note, that the association with a metatable is permanent and
<b>the metatable must not be modified afterwards!</b> Ditto for the
<tt>__index</tt> table.
</p>
<p>
<span class="mark">&#9317;</span> Here are some simple usage examples
for the point type and their expected results. The predefined
operations (such as <tt>a.x</tt>) can be freely mixed with the newly
defined metamethods. Note that <tt>area</tt> is a method and must be
called with the Lua syntax for methods: <tt>a:area()</tt>, not
<tt>a.area()</tt>.
</p>
<p>
The C&nbsp;type metamethod mechanism is most useful when used in
conjunction with C&nbsp;libraries that are written in an object-oriented
style. Creators return a pointer to a new instance, and methods take an
instance pointer as the first argument. Sometimes you can just point
<tt>__index</tt> to the library namespace and <tt>__gc</tt> to the
destructor and you're done. But often enough you'll want to add
convenience wrappers, e.g. to return actual Lua strings or when
returning multiple values.
</p>
<p>
Some C libraries only declare instance pointers as an opaque
<tt>void&nbsp;*</tt> type. In this case you can use a fake type for all
declarations, e.g. a pointer to a named (incomplete) struct will do:
<tt>typedef struct foo_type *foo_handle</tt>. The C&nbsp;side doesn't
know what you declare with the LuaJIT FFI, but as long as the underlying
types are compatible, everything still works.
</p>
<h2 id="idioms">Translating C&nbsp;Idioms</h2>
<p>
Here's a list of common C&nbsp;idioms and their translation to the
LuaJIT FFI:
</p>
<table class="idiomtable">
<tr class="idiomhead">
<td class="idiomdesc">Idiom</td>
<td class="idiomc">C&nbsp;code</td>
<td class="idiomlua">Lua code</td>
</tr>
<tr class="odd separate">
<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>
<tr class="even">
<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>
<tr class="odd">
<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>
<tr class="even separate">
<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>
<tr class="odd">
<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>
<tr class="even separate">
<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>
<tr class="odd">
<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>
<tr class="even">
<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>
<tr class="odd">
<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>
<tr class="even separate">
<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>
<tr class="odd">
<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>
</table>
<h2 id="cache">To Cache or Not to Cache</h2>
<p>
It's a common Lua idiom to cache library functions in local variables
or upvalues, e.g.:
</p>
<pre class="code">
local byte, char = string.byte, string.char
local function foo(x)
return char(byte(x)+1)
end
</pre>
<p>
This replaces several hash-table lookups with a (faster) direct use of
a local or an upvalue. This is less important with LuaJIT, since the
JIT compiler optimizes hash-table lookups a lot and is even able to
hoist most of them out of the inner loops. It can't eliminate
<em>all</em> of them, though, and it saves some typing for often-used
functions. So there's still a place for this, even with LuaJIT.
</p>
<p>
The situation is a bit different with C&nbsp;function calls via the
FFI library. The JIT compiler has special logic to eliminate <em>all
of the lookup overhead</em> for functions resolved from a
<a href="ext_ffi_semantics.html#clib">C&nbsp;library namespace</a>!
Thus it's not helpful and actually counter-productive to cache
individual C&nbsp;functions like this:
</p>
<pre class="code">
local <b>funca</b>, <b>funcb</b> = ffi.C.funca, ffi.C.funcb -- <span style="color:#c00000;">Not helpful!</span>
local function foo(x, n)
for i=1,n do <b>funcb</b>(<b>funca</b>(x, i), 1) end
end
</pre>
<p>
This turns them into indirect calls and generates bigger and slower
machine code. Instead, you'll want to cache the namespace itself and
rely on the JIT compiler to eliminate the lookups:
</p>
<pre class="code">
local <b>C</b> = ffi.C -- <span style="color:#00a000;">Instead use this!</span>
local function foo(x, n)
for i=1,n do <b>C.funcb</b>(<b>C.funca</b>(x, i), 1) end
end
</pre>
<p>
This generates both shorter and faster code. So <b>don't cache
C&nbsp;functions</b>, but <b>do</b> cache namespaces! Most often the
namespace is already in a local variable at an outer scope, e.g. from
<tt>local&nbsp;lib&nbsp;=&nbsp;ffi.load(...)</tt>. Note that copying
it to a local variable in the function scope is unnecessary.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

View File

@ -1,197 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>jit.* Library</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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><tt>jit.*</tt> 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 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 class="current" 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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 functions in this built-in module control the behavior of the JIT
compiler engine. Note that JIT-compilation is fully automatic &mdash;
you probably won't need to use any of the following functions unless
you have special needs.
</p>
<h3 id="jit_onoff"><tt>jit.on()<br>
jit.off()</tt></h3>
<p>
Turns the whole JIT compiler on (default) or off.
</p>
<p>
These functions are typically used with the command line options
<tt>-j on</tt> or <tt>-j off</tt>.
</p>
<h3 id="jit_flush"><tt>jit.flush()</tt></h3>
<p>
Flushes the whole cache of compiled code.
</p>
<h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br>
jit.off(func|true [,true|false])<br>
jit.flush(func|true [,true|false])</tt></h3>
<p>
<tt>jit.on</tt> enables JIT compilation for a Lua function (this is
the default).
</p>
<p>
<tt>jit.off</tt> disables JIT compilation for a Lua function and
flushes any already compiled code from the code cache.
</p>
<p>
<tt>jit.flush</tt> flushes the code, but doesn't affect the
enable/disable status.
</p>
<p>
The current function, i.e. the Lua function calling this library
function, can also be specified by passing <tt>true</tt> as the first
argument.
</p>
<p>
If the second argument is <tt>true</tt>, JIT compilation is also
enabled, disabled or flushed recursively for all sub-functions of a
function. With <tt>false</tt> only the sub-functions are affected.
</p>
<p>
The <tt>jit.on</tt> and <tt>jit.off</tt> functions only set a flag
which is checked when the function is about to be compiled. They do
not trigger immediate compilation.
</p>
<p>
Typical usage is <tt>jit.off(true, true)</tt> in the main chunk
of a module to turn off JIT compilation for the whole module for
debugging purposes.
</p>
<h3 id="jit_flush_tr"><tt>jit.flush(tr)</tt></h3>
<p>
Flushes the root trace, specified by its number, and all of its side
traces from the cache. The code for the trace will be retained as long
as there are any other traces which link to it.
</p>
<h3 id="jit_status"><tt>status, ... = jit.status()</tt></h3>
<p>
Returns the current status of the JIT compiler. The first result is
either <tt>true</tt> or <tt>false</tt> if the JIT compiler is turned
on or off. The remaining results are strings for CPU-specific features
and enabled optimizations.
</p>
<h3 id="jit_version"><tt>jit.version</tt></h3>
<p>
Contains the LuaJIT version string.
</p>
<h3 id="jit_version_num"><tt>jit.version_num</tt></h3>
<p>
Contains the version number of the LuaJIT core. Version xx.yy.zz
is represented by the decimal number xxyyzz.<br>
<b>DEPRECATED after the switch to
<a href="https://luajit.org/status.html#release"><span class="ext">&raquo;</span>&nbsp;rolling releases</a>. zz is frozen at 99.</b>
</p>
<h3 id="jit_os"><tt>jit.os</tt></h3>
<p>
Contains the target OS name:
"Windows", "Linux", "OSX", "BSD", "POSIX" or "Other".
</p>
<h3 id="jit_arch"><tt>jit.arch</tt></h3>
<p>
Contains the target architecture name:
"x86", "x64", "arm", "arm64", "arm64be", "ppc", "mips", "mipsel", "mips64", "mips64el", "mips64r6", "mips64r6el".
</p>
<h2 id="jit_opt"><tt>jit.opt.*</tt> &mdash; JIT compiler optimization control</h2>
<p>
This submodule provides the backend for the <tt>-O</tt> command line
option.
</p>
<p>
You can also use it programmatically, e.g.:
</p>
<pre class="code">
jit.opt.start(2) -- same as -O2
jit.opt.start("-dce")
jit.opt.start("hotloop=10", "hotexit=2")
</pre>
<p>
Unlike in LuaJIT 1.x, the module is built-in and
<b>optimization is turned on by default!</b>
It's no longer necessary to run <tt>require("jit.opt").start()</tt>,
which was one of the ways to enable optimization.
</p>
<h2 id="jit_util"><tt>jit.util.*</tt> &mdash; JIT compiler introspection</h2>
<p>
This submodule holds functions to introspect the bytecode, generated
traces, the IR and the generated machine code. The functionality
provided by this module is still in flux and therefore undocumented.
</p>
<p>
The debug modules <tt>-jbc</tt>, <tt>-jv</tt> and <tt>-jdump</tt> make
extensive use of these functions. Please check out their source code,
if you want to know more.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

View File

@ -1,359 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Profiler</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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>Profiler</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 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 class="current" href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
LuaJIT has an integrated statistical profiler with very low overhead. It
allows sampling the currently executing stack and other parameters in
regular intervals.
</p>
<p>
The integrated profiler can be accessed from three levels:
</p>
<ul>
<li>The <a href="#hl_profiler">bundled high-level profiler</a>, invoked by the
<a href="#j_p"><tt>-jp</tt></a> command line option.</li>
<li>A <a href="#ll_lua_api">low-level Lua API</a> to control the profiler.</li>
<li>A <a href="#ll_c_api">low-level C API</a> to control the profiler.</li>
</ul>
<h2 id="hl_profiler">High-Level Profiler</h2>
<p>
The bundled high-level profiler offers basic profiling functionality. It
generates simple textual summaries or source code annotations. It can be
accessed with the <a href="#j_p"><tt>-jp</tt></a> command line option
or from Lua code by loading the underlying <tt>jit.p</tt> module.
</p>
<p>
To cut to the chase &mdash; run this to get a CPU usage profile by
function name:
</p>
<pre class="code">
luajit -jp myapp.lua
</pre>
<p>
It's <em>not</em> a stated goal of the bundled profiler to add every
possible option or to cater for special profiling needs. The low-level
profiler APIs are documented below. They may be used by third-party
authors to implement advanced functionality, e.g. IDE integration or
graphical profilers.
</p>
<p>
Note: Sampling works for both interpreted and JIT-compiled code. The
results for JIT-compiled code may sometimes be surprising. LuaJIT
heavily optimizes and inlines Lua code &mdash; there's no simple
one-to-one correspondence between source code lines and the sampled
machine code.
</p>
<h3 id="j_p"><tt>-jp=[options[,output]]</tt></h3>
<p>
The <tt>-jp</tt> command line option starts the high-level profiler.
When the application run by the command line terminates, the profiler
stops and writes the results to <tt>stdout</tt> or to the specified
<tt>output</tt> file.
</p>
<p>
The <tt>options</tt> argument specifies how the profiling is to be
performed:
</p>
<ul>
<li><tt>f</tt> &mdash; Stack dump: function name, otherwise module:line.
This is the default mode.</li>
<li><tt>F</tt> &mdash; Stack dump: ditto, but dump module:name.</li>
<li><tt>l</tt> &mdash; Stack dump: module:line.</li>
<li><tt>&lt;number&gt;</tt> &mdash; stack dump depth (callee &larr;
caller). Default: 1.</li>
<li><tt>-&lt;number&gt;</tt> &mdash; Inverse stack dump depth (caller
&rarr; callee).</li>
<li><tt>s</tt> &mdash; Split stack dump after first stack level. Implies
depth&nbsp;&ge;&nbsp;2 or depth&nbsp;&le;&nbsp;-2.</li>
<li><tt>p</tt> &mdash; Show full path for module names.</li>
<li><tt>v</tt> &mdash; Show VM states.</li>
<li><tt>z</tt> &mdash; Show <a href="#jit_zone">zones</a>.</li>
<li><tt>r</tt> &mdash; Show raw sample counts. Default: show percentages.</li>
<li><tt>a</tt> &mdash; Annotate excerpts from source code files.</li>
<li><tt>A</tt> &mdash; Annotate complete source code files.</li>
<li><tt>G</tt> &mdash; Produce raw output suitable for graphical tools.</li>
<li><tt>m&lt;number&gt;</tt> &mdash; Minimum sample percentage to be shown.
Default: 3%.</li>
<li><tt>i&lt;number&gt;</tt> &mdash; Sampling interval in milliseconds.
Default: 10ms.<br>
Note: The actual sampling precision is OS-dependent.</li>
</ul>
<p>
The default output for <tt>-jp</tt> is a list of the most CPU consuming
spots in the application. Increasing the stack dump depth with (say)
<tt>-jp=2</tt> may help to point out the main callers or callees of
hotspots. But sample aggregation is still flat per unique stack dump.
</p>
<p>
To get a two-level view (split view) of callers/callees, use
<tt>-jp=s</tt> or <tt>-jp=-s</tt>. The percentages shown for the second
level are relative to the first level.
</p>
<p>
To see how much time is spent in each line relative to a function, use
<tt>-jp=fl</tt>.
</p>
<p>
To see how much time is spent in different VM states or
<a href="#jit_zone">zones</a>, use <tt>-jp=v</tt> or <tt>-jp=z</tt>.
</p>
<p>
Combinations of <tt>v/z</tt> with <tt>f/F/l</tt> produce two-level
views, e.g. <tt>-jp=vf</tt> or <tt>-jp=fv</tt>. This shows the time
spent in a VM state or zone vs. hotspots. This can be used to answer
questions like "Which time-consuming functions are only interpreted?" or
"What's the garbage collector overhead for a specific function?".
</p>
<p>
Multiple options can be combined &mdash; but not all combinations make
sense, see above. E.g. <tt>-jp=3si4m1</tt> samples three stack levels
deep in 4ms intervals and shows a split view of the CPU consuming
functions and their callers with a 1% threshold.
</p>
<p>
Source code annotations produced by <tt>-jp=a</tt> or <tt>-jp=A</tt> are
always flat and at the line level. Obviously, the source code files need
to be readable by the profiler script.
</p>
<p>
The high-level profiler can also be started and stopped from Lua code with:
</p>
<pre class="code">
require("jit.p").start(options, output)
...
require("jit.p").stop()
</pre>
<h3 id="jit_zone"><tt>jit.zone</tt> &mdash; Zones</h3>
<p>
Zones can be used to provide information about different parts of an
application to the high-level profiler. E.g. a game could make use of an
<tt>"AI"</tt> zone, a <tt>"PHYS"</tt> zone, etc. Zones are hierarchical,
organized as a stack.
</p>
<p>
The <tt>jit.zone</tt> module needs to be loaded explicitly:
</p>
<pre class="code">
local zone = require("jit.zone")
</pre>
<ul>
<li><tt>zone("name")</tt> pushes a named zone to the zone stack.</li>
<li><tt>zone()</tt> pops the current zone from the zone stack and
returns its name.</li>
<li><tt>zone:get()</tt> returns the current zone name or <tt>nil</tt>.</li>
<li><tt>zone:flush()</tt> flushes the zone stack.</li>
</ul>
<p>
To show the time spent in each zone use <tt>-jp=z</tt>. To show the time
spent relative to hotspots use e.g. <tt>-jp=zf</tt> or <tt>-jp=fz</tt>.
</p>
<h2 id="ll_lua_api">Low-level Lua API</h2>
<p>
The <tt>jit.profile</tt> module gives access to the low-level API of the
profiler from Lua code. This module needs to be loaded explicitly:
<pre class="code">
local profile = require("jit.profile")
</pre>
<p>
This module can be used to implement your own higher-level profiler.
A typical profiling run starts the profiler, captures stack dumps in
the profiler callback, adds them to a hash table to aggregate the number
of samples, stops the profiler and then analyzes all captured
stack dumps. Other parameters can be sampled in the profiler callback,
too. But it's important not to spend too much time in the callback,
since this may skew the statistics.
</p>
<h3 id="profile_start"><tt>profile.start(mode, cb)</tt>
&mdash; Start profiler</h3>
<p>
This function starts the profiler. The <tt>mode</tt> argument is a
string holding options:
</p>
<ul>
<li><tt>f</tt> &mdash; Profile with precision down to the function level.</li>
<li><tt>l</tt> &mdash; Profile with precision down to the line level.</li>
<li><tt>i&lt;number&gt;</tt> &mdash; Sampling interval in milliseconds (default
10ms).</br>
Note: The actual sampling precision is OS-dependent.
</li>
</ul>
<p>
The <tt>cb</tt> argument is a callback function which is called with
three arguments: <tt>(thread, samples, vmstate)</tt>. The callback is
called on a separate coroutine, the <tt>thread</tt> argument is the
state that holds the stack to sample for profiling. Note: do
<em>not</em> modify the stack of that state or call functions on it.
</p>
<p>
<tt>samples</tt> gives the number of accumulated samples since the last
callback (usually 1).
</p>
<p>
<tt>vmstate</tt> holds the VM state at the time the profiling timer
triggered. This may or may not correspond to the state of the VM when
the profiling callback is called. The state is either <tt>'N'</tt>
native (compiled) code, <tt>'I'</tt> interpreted code, <tt>'C'</tt>
C&nbsp;code, <tt>'G'</tt> the garbage collector, or <tt>'J'</tt> the JIT
compiler.
</p>
<h3 id="profile_stop"><tt>profile.stop()</tt>
&mdash; Stop profiler</h3>
<p>
This function stops the profiler.
</p>
<h3 id="profile_dump"><tt>dump = profile.dumpstack([thread,] fmt, depth)</tt>
&mdash; Dump stack </h3>
<p>
This function allows taking stack dumps in an efficient manner. It
returns a string with a stack dump for the <tt>thread</tt> (coroutine),
formatted according to the <tt>fmt</tt> argument:
</p>
<ul>
<li><tt>p</tt> &mdash; Preserve the full path for module names. Otherwise,
only the file name is used.</li>
<li><tt>f</tt> &mdash; Dump the function name if it can be derived. Otherwise,
use module:line.</li>
<li><tt>F</tt> &mdash; Ditto, but dump module:name.</li>
<li><tt>l</tt> &mdash; Dump module:line.</li>
<li><tt>Z</tt> &mdash; Zap the following characters for the last dumped
frame.</li>
<li>All other characters are added verbatim to the output string.</li>
</ul>
<p>
The <tt>depth</tt> argument gives the number of frames to dump, starting
at the topmost frame of the thread. A negative number dumps the frames in
inverse order.
</p>
<p>
The first example prints a list of the current module names and line
numbers of up to 10 frames in separate lines. The second example prints
semicolon-separated function names for all frames (up to 100) in inverse
order:
</p>
<pre class="code">
print(profile.dumpstack(thread, "l\n", 10))
print(profile.dumpstack(thread, "lZ;", -100))
</pre>
<h2 id="ll_c_api">Low-level C API</h2>
<p>
The profiler can be controlled directly from C&nbsp;code, e.g. for
use by IDEs. The declarations are in <tt>"luajit.h"</tt> (see
<a href="ext_c_api.html">Lua/C API</a> extensions).
</p>
<h3 id="luaJIT_profile_start"><tt>luaJIT_profile_start(L, mode, cb, data)</tt>
&mdash; Start profiler</h3>
<p>
This function starts the profiler. <a href="#profile_start">See
above</a> for a description of the <tt>mode</tt> argument.
</p>
<p>
The <tt>cb</tt> argument is a callback function with the following
declaration:
</p>
<pre class="code">
typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
int samples, int vmstate);
</pre>
<p>
<tt>data</tt> is available for use by the callback. <tt>L</tt> is the
state that holds the stack to sample for profiling. Note: do
<em>not</em> modify this stack or call functions on this stack &mdash;
use a separate coroutine for this purpose. <a href="#profile_start">See
above</a> for a description of <tt>samples</tt> and <tt>vmstate</tt>.
</p>
<h3 id="luaJIT_profile_stop"><tt>luaJIT_profile_stop(L)</tt>
&mdash; Stop profiler</h3>
<p>
This function stops the profiler.
</p>
<h3 id="luaJIT_profile_dumpstack"><tt>p = luaJIT_profile_dumpstack(L, fmt, depth, len)</tt>
&mdash; Dump stack </h3>
<p>
This function allows taking stack dumps in an efficient manner.
<a href="#profile_dump">See above</a> for a description of <tt>fmt</tt>
and <tt>depth</tt>.
</p>
<p>
This function returns a <tt>const&nbsp;char&nbsp;*</tt> pointing to a
private string buffer of the profiler. The <tt>int&nbsp;*len</tt>
argument returns the length of the output string. The buffer is
overwritten on the next call and deallocated when the profiler stops.
You either need to consume the content immediately or copy it for later
use.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

View File

@ -1,502 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Extensions</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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">
table.exc {
line-height: 1.2;
}
tr.exchead td {
font-weight: bold;
}
td.excplatform {
width: 48%;
}
td.exccompiler {
width: 29%;
}
td.excinterop {
width: 23%;
}
</style>
</head>
<body>
<div id="site">
<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1>Extensions</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 class="current" href="extensions.html">Extensions</a>
<ul><li>
<a 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
LuaJIT is fully upwards-compatible with Lua 5.1. It supports all
<a href="https://www.lua.org/manual/5.1/manual.html#5"><span class="ext">&raquo;</span>&nbsp;standard Lua
library functions</a> and the full set of
<a href="https://www.lua.org/manual/5.1/manual.html#3"><span class="ext">&raquo;</span>&nbsp;Lua/C API
functions</a>.
</p>
<p>
LuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic
loader level. This means you can compile a C&nbsp;module against the
standard Lua headers and load the same shared library from either Lua
or LuaJIT.
</p>
<p>
LuaJIT extends the standard Lua VM with new functionality and adds
several extension modules. Please note, this page is only about
<em>functional</em> enhancements and not about performance enhancements,
such as the optimized VM, the faster interpreter or the JIT compiler.
</p>
<h2 id="modules">Extensions Modules</h2>
<p>
LuaJIT comes with several built-in extension modules:
</p>
<h3 id="bit"><tt>bit.*</tt> &mdash; Bitwise operations</h3>
<p>
LuaJIT supports all bitwise operations as defined by
<a href="https://bitop.luajit.org"><span class="ext">&raquo;</span>&nbsp;Lua BitOp</a>:
</p>
<pre class="code">
bit.tobit bit.tohex bit.bnot bit.band bit.bor bit.bxor
bit.lshift bit.rshift bit.arshift bit.rol bit.ror bit.bswap
</pre>
<p>
This module is a LuaJIT built-in &mdash; you don't need to download or
install Lua BitOp. The Lua BitOp site has full documentation for all
<a href="https://bitop.luajit.org/api.html"><span class="ext">&raquo;</span>&nbsp;Lua BitOp API functions</a>.
The FFI adds support for
<a href="ext_ffi_semantics.html#cdata_arith">64&nbsp;bit bitwise operations</a>,
using the same API functions.
</p>
<p>
Please make sure to <tt>require</tt> the module before using any of
its functions:
</p>
<pre class="code">
local bit = require("bit")
</pre>
<p>
An already installed Lua BitOp module is ignored by LuaJIT.
This way you can use bit operations from both Lua and LuaJIT on a
shared installation.
</p>
<h3 id="ffi"><tt>ffi.*</tt> &mdash; FFI library</h3>
<p>
The <a href="ext_ffi.html">FFI library</a> allows calling external
C&nbsp;functions and the use of C&nbsp;data structures from pure Lua
code.
</p>
<h3 id="jit"><tt>jit.*</tt> &mdash; JIT compiler control</h3>
<p>
The functions in this module
<a href="ext_jit.html">control the behavior of the JIT compiler engine</a>.
</p>
<h3 id="c_api">C API extensions</h3>
<p>
LuaJIT adds some
<a href="ext_c_api.html">extra functions to the Lua/C API</a>.
</p>
<h3 id="profiler">Profiler</h3>
<p>
LuaJIT has an <a href="ext_profiler.html">integrated profiler</a>.
</p>
<h2 id="library">Enhanced Standard Library Functions</h2>
<h3 id="xpcall"><tt>xpcall(f, err [,args...])</tt> passes arguments</h3>
<p>
Unlike the standard implementation in Lua 5.1, <tt>xpcall()</tt>
passes any arguments after the error function to the function
which is called in a protected context.
</p>
<h3 id="load"><tt>load*()</tt> handle UTF-8 source code</h3>
<p>
Non-ASCII characters are handled transparently by the Lua source code parser.
This allows the use of UTF-8 characters in identifiers and strings.
A UTF-8 BOM is skipped at the start of the source code.
</p>
<h3 id="load_mode"><tt>load*()</tt> add a mode parameter</h3>
<p>
As an extension from Lua 5.2, the functions <tt>loadstring()</tt>,
<tt>loadfile()</tt> and (new) <tt>load()</tt> add an optional
<tt>mode</tt> parameter.
</p>
<p>
The default mode string is <tt>"bt"</tt>, which allows loading of both
source code and bytecode. Use <tt>"t"</tt> to allow only source code
or <tt>"b"</tt> to allow only bytecode to be loaded.
</p>
<p>
By default, the <tt>load*</tt> functions generate the native bytecode format.
For cross-compilation purposes, add <tt>W</tt> to the mode string to
force the 32 bit format and <tt>X</tt> to force the 64 bit format.
Add both to force the opposite format. Note that non-native bytecode
generated by <tt>load*</tt> cannot be run, but can still be passed
to <tt>string.dump</tt>.
</p>
<h3 id="tostring"><tt>tostring()</tt> etc. canonicalize NaN and &plusmn;Inf</h3>
<p>
All number-to-string conversions consistently convert non-finite numbers
to the same strings on all platforms. NaN results in <tt>"nan"</tt>,
positive infinity results in <tt>"inf"</tt> and negative infinity results
in <tt>"-inf"</tt>.
</p>
<h3 id="tonumber"><tt>tonumber()</tt> etc. use builtin string to number conversion</h3>
<p>
All string-to-number conversions consistently convert integer and
floating-point inputs in decimal, hexadecimal and binary on all platforms.
<tt>strtod()</tt> is <em>not</em> used anymore, which avoids numerous
problems with poor C library implementations. The builtin conversion
function provides full precision according to the IEEE-754 standard, it
works independently of the current locale and it supports hex floating-point
numbers (e.g. <tt>0x1.5p-3</tt>).
</p>
<h3 id="string_dump"><tt>string.dump(f [,mode])</tt> generates portable bytecode</h3>
<p>
An extra argument has been added to <tt>string.dump()</tt>. If set to
<tt>true</tt> or to a string which contains the character <tt>s</tt>,
'stripped' bytecode without debug information is generated. This speeds
up later bytecode loading and reduces memory usage. See also the
<a href="running.html#opt_b"><tt>-b</tt> command line option</a>.
</p>
<p>
The generated bytecode is portable and can be loaded on any architecture
that LuaJIT supports. However, the bytecode compatibility versions must
match. Bytecode only stays compatible within a major+minor version
(x.y.aaa &rarr; x.y.bbb), except for development branches. Foreign bytecode
(e.g. from Lua 5.1) is incompatible and cannot be loaded.
</p>
<p>
Note: <tt>LJ_GC64</tt> mode requires a different frame layout, which implies
a different, incompatible bytecode format between 32 bit and 64 bit ports.
This may be rectified in the future. In the meantime, use the <tt>W</tt>
and </tt>X</tt> <a href="#load_mode">modes of the <tt>load*</tt> functions</a>
for cross-compilation purposes.
</p>
<p>
Due to VM hardening, bytecode is not deterministic. Add <tt>d</tt> to the
mode string to dump it in a deterministic manner: identical source code
always gives a byte-for-byte identical bytecode dump. This feature is
mainly useful for reproducible builds.
</p>
<h3 id="table_new"><tt>table.new(narray, nhash)</tt> allocates a pre-sized table</h3>
<p>
An extra library function <tt>table.new()</tt> can be made available via
<tt>require("table.new")</tt>. This creates a pre-sized table, just like
the C API equivalent <tt>lua_createtable()</tt>. This is useful for big
tables if the final table size is known and automatic table resizing is
too expensive.
</p>
<h3 id="table_clear"><tt>table.clear(tab)</tt> clears a table</h3>
<p>
An extra library function <tt>table.clear()</tt> can be made available
via <tt>require("table.clear")</tt>. This clears all keys and values
from a table, but preserves the allocated array/hash sizes. This is
useful when a table, which is linked from multiple places, needs to be
cleared and/or when recycling a table for use by the same context. This
avoids managing backlinks, saves an allocation and the overhead of
incremental array/hash part growth.
</p>
<p>
Please note, this function is meant for very specific situations. In most
cases it's better to replace the (usually single) link with a new table
and let the GC do its work.
</p>
<h3 id="math_random">Enhanced PRNG for <tt>math.random()</tt></h3>
<p>
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of
the PRNG results is much superior compared to the standard Lua
implementation, which uses the platform-specific ANSI <tt>rand()</tt>.
</p>
<p>
The PRNG generates the same sequences from the same seeds on all
platforms and makes use of all bits in the seed argument.
<tt>math.random()</tt> without arguments generates 52 pseudo-random bits
for every call. The result is uniformly distributed between 0.0 and 1.0.
It's correctly scaled up and rounded for <tt>math.random(n&nbsp;[,m])</tt> to
preserve uniformity.
</p>
<p>
Call <tt>math.randomseed()</tt> without any arguments to seed it from
system entropy.
</p>
<p>
Important: Neither this nor any other PRNG based on the simplistic
<tt>math.random()</tt> API is suitable for cryptographic use.
</p>
<h3 id="io"><tt>io.*</tt> functions handle 64&nbsp;bit file offsets</h3>
<p>
The file I/O functions in the standard <tt>io.*</tt> library handle
64&nbsp;bit file offsets. In particular, this means it's possible
to open files larger than 2&nbsp;Gigabytes and to reposition or obtain
the current file position for offsets beyond 2&nbsp;GB
(<tt>fp:seek()</tt> method).
</p>
<h3 id="debug_meta"><tt>debug.*</tt> functions identify metamethods</h3>
<p>
<tt>debug.getinfo()</tt> and <tt>lua_getinfo()</tt> also return information
about invoked metamethods. The <tt>namewhat</tt> field is set to
<tt>"metamethod"</tt> and the <tt>name</tt> field has the name of
the corresponding metamethod (e.g. <tt>"__index"</tt>).
</p>
<h2 id="resumable">Fully Resumable VM</h2>
<p>
The LuaJIT VM is fully resumable. This means you can yield from a
coroutine even across contexts, where this would not possible with
the standard Lua&nbsp;5.1 VM: e.g. you can yield across <tt>pcall()</tt>
and <tt>xpcall()</tt>, across iterators and across metamethods.
</p>
<h2 id="lua52">Extensions from Lua 5.2</h2>
<p>
LuaJIT supports some language and library extensions from Lua&nbsp;5.2.
Features that are unlikely to break existing code are unconditionally
enabled:
</p>
<ul>
<li><tt>goto</tt> and <tt>::labels::</tt>.</li>
<li>Hex escapes <tt>'\x3F'</tt> and <tt>'\z'</tt> escape in strings.</li>
<li><tt>load(string|reader [, chunkname [,mode [,env]]])</tt>.</li>
<li><tt>loadstring()</tt> is an alias for <tt>load()</tt>.</li>
<li><tt>loadfile(filename [,mode [,env]])</tt>.</li>
<li><tt>math.log(x [,base])</tt>.</li>
<li><tt>string.rep(s, n [,sep])</tt>.</li>
<li><tt>string.format()</tt>: <tt>%q</tt> reversible.
<tt>%s</tt> checks <tt>__tostring</tt>.
<tt>%a</tt> and <tt>"%A</tt> added.</li>
<li>String matching pattern <tt>%g</tt> added.</li>
<li><tt>io.read("*L")</tt>.</li>
<li><tt>io.lines()</tt> and <tt>file:lines()</tt> process
<tt>io.read()</tt> options.</li>
<li><tt>os.exit(status|true|false [,close])</tt>.</li>
<li><tt>package.searchpath(name, path [, sep [, rep]])</tt>.</li>
<li><tt>package.loadlib(name, "*")</tt>.</li>
<li><tt>debug.getinfo()</tt> returns <tt>nparams</tt> and <tt>isvararg</tt>
for option <tt>"u"</tt>.</li>
<li><tt>debug.getlocal()</tt> accepts function instead of level.</li>
<li><tt>debug.getlocal()</tt> and <tt>debug.setlocal()</tt> accept negative
indexes for varargs.</li>
<li><tt>debug.getupvalue()</tt> and <tt>debug.setupvalue()</tt> handle
C&nbsp;functions.</li>
<li><tt>debug.upvalueid()</tt> and <tt>debug.upvaluejoin()</tt>.</li>
<li>Lua/C API extensions:
<tt>lua_version()</tt>
<tt>lua_upvalueid()</tt>
<tt>lua_upvaluejoin()</tt>
<tt>lua_loadx()</tt>
<tt>lua_copy()</tt>
<tt>lua_tonumberx()</tt>
<tt>lua_tointegerx()</tt>
<tt>luaL_fileresult()</tt>
<tt>luaL_execresult()</tt>
<tt>luaL_loadfilex()</tt>
<tt>luaL_loadbufferx()</tt>
<tt>luaL_traceback()</tt>
<tt>luaL_setfuncs()</tt>
<tt>luaL_pushmodule()</tt>
<tt>luaL_newlibtable()</tt>
<tt>luaL_newlib()</tt>
<tt>luaL_testudata()</tt>
<tt>luaL_setmetatable()</tt>
</li>
<li>Command line option <tt>-E</tt>.</li>
<li>Command line checks <tt>__tostring</tt> for errors.</li>
</ul>
<p>
Other features are only enabled, if LuaJIT is built with
<tt>-DLUAJIT_ENABLE_LUA52COMPAT</tt>:
</p>
<ul>
<li><tt>goto</tt> is a keyword and not a valid variable name anymore.</li>
<li><tt>break</tt> can be placed anywhere. Empty statements (<tt>;;</tt>)
are allowed.</li>
<li><tt>__lt</tt>, <tt>__le</tt> are invoked for mixed types.</li>
<li><tt>__len</tt> for tables. <tt>rawlen()</tt> library function.</li>
<li><tt>pairs()</tt> and <tt>ipairs()</tt> check for <tt>__pairs</tt> and
<tt>__ipairs</tt>.</li>
<li><tt>coroutine.running()</tt> returns two results.</li>
<li><tt>table.pack()</tt> and <tt>table.unpack()</tt>
(same as <tt>unpack()</tt>).</li>
<li><tt>io.write()</tt> and <tt>file:write()</tt> return file handle
instead of <tt>true</tt>.</li>
<li><tt>os.execute()</tt> and <tt>pipe:close()</tt> return detailed
exit status.</li>
<li><tt>debug.setmetatable()</tt> returns object.</li>
<li><tt>debug.getuservalue()</tt> and <tt>debug.setuservalue()</tt>.</li>
<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.</li>
<li><tt>package.searchers</tt>.</li>
<li><tt>module()</tt> returns the module table.</li>
</ul>
<p>
Note: this provides only partial compatibility with Lua 5.2 at the
language and Lua library level. LuaJIT is API+ABI-compatible with
Lua&nbsp;5.1, which prevents implementing features that would otherwise
break the Lua/C API and ABI (e.g. <tt>_ENV</tt>).
</p>
<h2 id="lua53">Extensions from Lua 5.3</h2>
<p>
LuaJIT supports some extensions from Lua&nbsp;5.3:
<ul>
<li>Unicode escape <tt>'\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li>
<li>The argument table <tt>arg</tt> can be read (and modified) by <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>
<li><tt>io.read()</tt> and <tt>file:read()</tt> accept formats with or without a leading <tt>*</tt>.</li>
<li><tt>assert()</tt> accepts any type of error object.</li>
<li><tt>table.move(a1, f, e, t [,a2])</tt>.</li>
<li><tt>coroutine.isyieldable()</tt>.</li>
<li>Lua/C API extensions:
<tt>lua_isyieldable()</tt>
</li>
</ul>
<h2 id="exceptions">C++ Exception Interoperability</h2>
<p>
LuaJIT has built-in support for interoperating with C++&nbsp;exceptions.
The available range of features depends on the target platform and
the toolchain used to compile LuaJIT:
</p>
<table class="exc">
<tr class="exchead">
<td class="excplatform">Platform</td>
<td class="exccompiler">Compiler</td>
<td class="excinterop">Interoperability</td>
</tr>
<tr class="odd separate">
<td class="excplatform">External frame unwinding</td>
<td class="exccompiler">GCC, Clang, MSVC</td>
<td class="excinterop"><b style="color: #00a000;">Full</b></td>
</tr>
<tr class="even">
<td class="excplatform">Internal frame unwinding + DWARF2</td>
<td class="exccompiler">GCC, Clang</td>
<td class="excinterop"><b style="color: #c06000;">Limited</b></td>
</tr>
<tr class="odd">
<td class="excplatform">Windows 64 bit</td>
<td class="exccompiler">non-MSVC</td>
<td class="excinterop"><b style="color: #c06000;">Limited</b></td>
</tr>
<tr class="even">
<td class="excplatform">Other platforms</td>
<td class="exccompiler">Other compilers</td>
<td class="excinterop"><b style="color: #a00000;">No</b></td>
</tr>
</table>
<p>
<b style="color: #00a000;">Full interoperability</b> means:
</p>
<ul>
<li>C++&nbsp;exceptions can be caught on the Lua side with <tt>pcall()</tt>,
<tt>lua_pcall()</tt> etc.</li>
<li>C++&nbsp;exceptions will be converted to the generic Lua error
<tt>"C++&nbsp;exception"</tt>, unless you use the
<a href="ext_c_api.html#mode_wrapcfunc">C&nbsp;call wrapper</a> feature.</li>
<li>It's safe to throw C++&nbsp;exceptions across non-protected Lua frames
on the C&nbsp;stack. The contents of the C++&nbsp;exception object
pass through unmodified.</li>
<li>Lua errors can be caught on the C++ side with <tt>catch(...)</tt>.
The corresponding Lua error message can be retrieved from the Lua stack.</li>
<li>Throwing Lua errors across C++ frames is safe. C++ destructors
will be called.</li>
</ul>
<p>
<b style="color: #c06000;">Limited interoperability</b> means:
</p>
<ul>
<li>C++&nbsp;exceptions can be caught on the Lua side with <tt>pcall()</tt>,
<tt>lua_pcall()</tt> etc.</li>
<li>C++&nbsp;exceptions will be converted to the generic Lua error
<tt>"C++&nbsp;exception"</tt>, unless you use the
<a href="ext_c_api.html#mode_wrapcfunc">C&nbsp;call wrapper</a> feature.</li>
<li>C++&nbsp;exceptions will be caught by non-protected Lua frames and
are rethrown as a generic Lua error. The C++&nbsp;exception object will
be destroyed.</li>
<li>Lua errors <b>cannot</b> be caught on the C++ side.</li>
<li>Throwing Lua errors across C++ frames will <b>not</b> call
C++ destructors.</li>
</ul>
<p>
<b style="color: #a00000;">No interoperability</b> means:
</p>
<ul>
<li>It's <b>not</b> safe to throw C++&nbsp;exceptions across Lua frames.</li>
<li>C++&nbsp;exceptions <b>cannot</b> be caught on the Lua side.</li>
<li>Lua errors <b>cannot</b> be caught on the C++ side.</li>
<li>Throwing Lua errors across C++ frames will <b>not</b> call
C++ destructors.</li>
</ul>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

338
doc/extensions/buffer.md Normal file
View File

@ -0,0 +1,338 @@
# String Buffer Library
The string buffer library allows **high-performance manipulation of string-like data**.
Unlike Lua strings, which are constants, string buffers are **mutable** sequences of 8-bit (binary-transparent) characters. Data can be stored, formatted and encoded into a string buffer and later converted, extracted or decoded.
The convenient string buffer API simplifies common string manipulation tasks, that would otherwise require creating many intermediate strings. String buffers improve performance by eliminating redundant memory copies, object creation, string interning and garbage collection overhead. In conjunction with the FFI library, they allow zero-copy operations.
The string buffer library also includes a high-performance [serializer](#serialize) for Lua objects.
## Using the String Buffer Library
The string buffer library is built into LuaJIT by default, but it's not loaded by default. Add this to the start of every Lua file that needs one of its functions:
```lua
local buffer = require "string.buffer";
```
The convention for the syntax shown on this page is that `buffer` refers to the buffer library and `buf` refers to an individual buffer object.
Please note the difference between a Lua function call, e.g. `buffer.new()` (with a dot) and a Lua method call, e.g. `buf:reset()` (with a colon).
### Buffer Objects
A buffer object is a garbage-collected Lua object. After creation with `buffer.new()`, it can (and should) be reused for many operations. When the last reference to a buffer object is gone, it will eventually be freed by the garbage collector, along with the allocated buffer space.
Buffers operate like a FIFO (first-in first-out) data structure. Data can be appended (written) to the end of the buffer and consumed (read) from the front of the buffer. These operations may be freely mixed.
The buffer space that holds the characters is managed automatically — it grows as needed and already consumed space is recycled. Use `buffer.new(size)` and `buf:free()`, if you need more control.
The maximum size of a single buffer is the same as the maximum size of a Lua string, which is slightly below two gigabytes. For huge data sizes, neither strings nor buffers are the right data structure — use the FFI library to directly map memory or files up to the virtual memory limit of your OS.
### Buffer Method Overview
- The `buf:put*()`-like methods append (write) characters to the end of the buffer.
- The `buf:get*()`-like methods consume (read) characters from the front of the buffer.
- Other methods, like `buf:tostring()` only read the buffer contents, but don't change the buffer.
- The `buf:set()` method allows zero-copy consumption of a string or an FFI cdata object as a buffer.
- The FFI-specific methods allow zero-copy read/write-style operations or modifying the buffer contents in-place. Please check the [FFI caveats](#ffi_caveats) below, too.
- Methods that don't need to return anything specific, return the buffer object itself as a convenience. This allows method chaining, e.g.: `buf:reset():encode(obj)` or `buf:skip(len):get()`
## Buffer Creation and Management
### `local buf = buffer.new([size [,options]])` `local buf = buffer.new([options])`
Creates a new buffer object.
The optional `size` argument ensures a minimum initial buffer size. This is strictly an optimization when the required buffer size is known beforehand. The buffer space will grow as needed, in any case.
The optional table `options` sets various [serialization options](#serialize_options).
### `buf = buf:reset()`
Reset (empty) the buffer. The allocated buffer space is not freed and may be reused.
### `buf = buf:free()`
The buffer space of the buffer object is freed. The object itself remains intact, empty and may be reused.
Note: you normally don't need to use this method. The garbage collector automatically frees the buffer space, when the buffer object is collected. Use this method, if you need to free the associated memory immediately.
## Buffer Writers
### `buf = buf:put([str|num|obj] [,…])`
Appends a string `str`, a number `num` or any object `obj` with a `__tostring` metamethod to the buffer. Multiple arguments are appended in the given order.
Appending a buffer to a buffer is possible and short-circuited internally. But it still involves a copy. Better combine the buffer writes to use a single buffer.
### `buf = buf:putf(format, …)`
Appends the formatted arguments to the buffer. The `format` string supports the same options as `string.format()`.
### `buf = buf:putcdata(cdata, len)` FFI
Appends the given `len` number of bytes from the memory pointed to by
the FFI `cdata` object to the buffer. The object needs to be convertible
to a (constant) pointer.
### `buf = buf:set(str)` `buf = buf:set(cdata, len)` FFI
This method allows zero-copy consumption of a string or an FFI cdata object as a buffer. It stores a reference to the passed string `str` or the FFI `cdata` object in the buffer. Any buffer space originally allocated is freed. This is *not* an append operation, unlike the `buf:put*()` methods.
After calling this method, the buffer behaves as if `buf:free():put(str)` or `buf:free():put(cdata, len)` had been called. However, the data is only referenced and not copied, as long as the buffer is only consumed.
In case the buffer is written to later on, the referenced data is copied and the object reference is removed (copy-on-write semantics).
The stored reference is an anchor for the garbage collector and keeps the originally passed string or FFI cdata object alive.
### `ptr, len = buf:reserve(size)` FFI `buf = buf:commit(used)` FFI
The `reserve` method reserves at least `size` bytes of write space in the buffer. It returns an `uint8_t *` FFI cdata pointer `ptr` that points to this space.
The available length in bytes is returned in `len`. This is at least `size` bytes, but may be more to facilitate efficient buffer growth. You can either make use of the additional space or ignore `len` and only use `size` bytes.
The `commit` method appends the `used` bytes of the previously returned write space to the buffer data.
This pair of methods allows zero-copy use of C read-style APIs:
```lua
local MIN_SIZE = 65536;
repeat
local ptr, len = buf:reserve(MIN_SIZE);
local n = C.read(fd, ptr, len);
if n == 0 then break end -- EOF.
if n < 0 then error "read error" end
buf:commit(n);
until false;
```
The reserved write space is *not* initialized. At least the `used` bytes
**must** be written to before calling the `commit` method. There's no
need to call the `commit` method, if nothing is added to the buffer
(e.g. on error).
## Buffer Readers
### `len = #buf`
Returns the current length of the buffer data in bytes.
### `res = str|num|buf .. str|num|buf […]`
The Lua concatenation operator `..` also accepts buffers, just like strings or numbers. It always returns a string and not a buffer.
Note that although this is supported for convenience, this thwarts one of the main reasons to use buffers, which is to avoid string allocations. Rewrite it with `buf:put()` and `buf:get()`.
Mixing this with unrelated objects that have a `__concat` metamethod may not work, since these probably only expect strings.
### `buf = buf:skip(len)`
Skips (consumes) `len` bytes from the buffer up to the current length of the buffer data.
### `str, … = buf:get([len|nil] [,…])`
Consumes the buffer data and returns one or more strings. If called without arguments, the whole buffer data is consumed. If called with a number, up to `len` bytes are consumed. A `nil` argument consumes the remaining buffer space (this only makes sense as the last argument). Multiple arguments consume the buffer data in the given order.
Note: a zero length or no remaining buffer data returns an empty string and not `nil`.
### `str = buf:tostring()` `str = tostring(buf)`
Creates a string from the buffer data, but doesn't consume it. The buffer remains unchanged.
Buffer objects also define a `__tostring` metamethod. This means buffers can be passed to the global `tostring()` function and many other functions that accept this in place of strings. The important internal uses in functions like `io.write()` are short-circuited to avoid the creation of an intermediate string object.
### `ptr, len = buf:ref()` <span class="lib">FFI</span>
Returns an `uint8_t *` FFI cdata pointer `ptr` that points to the buffer data. The length of the buffer data in bytes is returned in `len`.
The returned pointer can be directly passed to C functions that expect a buffer and a length. You can also do bytewise reads (`local x = ptr[i]`) or writes (`ptr[i] = 0x40`) of the buffer data.
In conjunction with the `skip` method, this allows zero-copy use of C write-style APIs:
```lua
repeat
local ptr, len = buf:ref();
if len == 0 then break end
local n = C.write(fd, ptr, len);
if n < 0 then error "write error" end
buf:skip(n);
until n >= len;
```
Unlike Lua strings, buffer data is *not* implicitly zero-terminated. It's not safe to pass `ptr` to C functions that expect zero-terminated strings. If you're not using `len`, then you're doing something wrong.
## Serialization of Lua Objects
The following functions and methods allow **high-speed serialization** (encoding) of a Lua object into a string and decoding it back to a Lua object. This allows convenient storage and transport of **structured data**.
The encoded data is in an [internal binary format](#serialize_format). The data can be stored in files, binary-transparent databases or transmitted to other LuaJIT instances across threads, processes or networks.
Encoding speed can reach up to 1 Gigabyte/second on a modern desktop - or server-class system, even when serializing many small objects. Decoding speed is mostly constrained by object creation cost.
The serializer handles most Lua types, common FFI number types and nested structures. Functions, thread objects, other FFI cdata and full userdata cannot be serialized (yet).
The encoder serializes nested structures as trees. Multiple references to a single object will be stored separately and create distinct objects after decoding. Circular references cause an error.
### Serialization Functions and Methods
### `str = buffer.encode(obj)` `buf = buf:encode(obj)`
Serializes (encodes) the Lua object `obj`. The stand-alone function returns a string `str`. The buffer method appends the encoding to the buffer.
`obj` can be any of the supported Lua types — it doesn't need to be a Lua table.
This function may throw an error when attempting to serialize unsupported object types, circular references or deeply nested tables.
### `obj = buffer.decode(str)` `obj = buf:decode()`
The stand-alone function deserializes (decodes) the string `str`, the buffer method deserializes one object from the buffer. Both return a Lua object `obj`.
The returned object may be any of the supported Lua types — even `nil`.
This function may throw an error when fed with malformed or incomplete encoded data. The stand-alone function throws when there's left-over data after decoding a single top-level object. The buffer method leaves any left-over data in the buffer.
Attempting to deserialize an FFI type will throw an error, if the FFI library is not built-in or has not been loaded, yet.
### Serialization Options
The `options` table passed to `buffer.new()` may contain the following members (all optional):
- `dict` is a Lua table holding a **dictionary of strings** that commonly occur as table keys of objects you are serializing. These keys are compactly encoded as indexes during serialization. A well-chosen dictionary saves space and improves serialization performance.
- `metatable` is a Lua table holding a **dictionary of metatables** for the table objects you are serializing.
`dict` needs to be an array of strings and `metatable` needs to be an array of tables. Both starting at index 1 and without holes (no `nil` in between). The tables are anchored in the buffer object and internally modified into a two-way index (don't do this yourself, just pass a plain array). The tables must not be modified after they have been passed to `buffer.new()`.
The `dict` and `metatable` tables used by the encoder and decoder must be the same. Put the most common entries at the front. Extend at the end to ensure backwards-compatibility — older encodings can then still be read. You may also set some indexes to `false` to explicitly drop backwards-compatibility. Old encodings that use these indexes will throw an error when decoded.
Metatables that are not found in the `metatable` dictionary are ignored when encoding. Decoding returns a table with a `nil` metatable.
Note: parsing and preparation of the options table is somewhat expensive. Create a buffer object only once and recycle it for multiple uses. Avoid mixing encoder and decoder buffers, since the `buf:set()` method frees the already allocated buffer space:
```lua
local options = { dict = { "commonly", "used", "string", "keys" } };
local buf_enc = buffer.new(options);
local buf_dec = buffer.new(options);
local function encode(obj)
return buf_enc:reset():encode(obj):get();
end
local function decode(str)
return buf_dec:set(str):decode();
end
```
### Streaming Serialization
In some contexts, it's desirable to do piecewise serialization of large datasets, also known as *streaming*.
This serialization format can be safely concatenated and supports streaming. Multiple encodings can simply be appended to a buffer and later decoded individually:
```lua
local buf = buffer.new();
buf:encode(obj1);
buf:encode(obj2);
local copy1 = buf:decode();
local copy2 = buf:decode();
```
Here's how to iterate over a stream:
```lua
while #buf ~= 0 do
local obj = buf:decode();
-- Do something with obj
end
```
Since the serialization format doesn't prepend a length to its encoding, network applications may need to transmit the length, too.
### Serialization Format Specification
This serialization format is designed for **internal use** by LuaJIT applications. Serialized data is upwards-compatible and portable across all supported LuaJIT platforms.
It's an **8-bit binary format** and not human-readable. It uses e.g. embedded zeroes and stores embedded Lua string objects unmodified, which are 8-bit-clean, too. Encoded data can be safely concatenated for streaming and later decoded one top-level object at a time.
The encoding is reasonably compact, but tuned for maximum performance, not for minimum space usage. It compresses well with any of the common byte-oriented data compression algorithms.
Although documented here for reference, this format is explicitly **not** intended to be a 'public standard' for structured data interchange across computer languages (like JSON or MessagePack). Please do not use it as such.
The specification is given below as a context-free grammar with a top-level `object` as the starting point. Alternatives are separated by the `|` symbol and `*` indicates repeats. Grouping is implicit or indicated by `{…}`. Terminals are either plain hex numbers, encoded as bytes, or have a `.format` suffix.
```
object → nil | false | true
| null | lightud32 | lightud64
| int | num | tab | tab_mt
| int64 | uint64 | complex
| string
nil → 0x00
false → 0x01
true → 0x02
null → 0x03 // NULL lightuserdata
lightud32 → 0x04 data.I // 32 bit lightuserdata
lightud64 → 0x05 data.L // 64 bit lightuserdata
int → 0x06 int.I // int32_t
num → 0x07 double.L
tab → 0x08 // Empty table
| 0x09 h.U h*{object object} // Key/value hash
| 0x0a a.U a*object // 0-based array
| 0x0b a.U h.U a*object h*{object object} // Mixed
| 0x0c a.U (a-1)*object // 1-based array
| 0x0d a.U h.U (a-1)*object h*{object object} // Mixed
tab_mt → 0x0e (index-1).U tab // Metatable dict entry
int64 → 0x10 int.L // FFI int64_t
uint64 → 0x11 uint.L // FFI uint64_t
complex → 0x12 re.L im.L // FFI complex
string → (0x20+len).U len*char.B
| 0x0f (index-1).U // String dict entry
.B = 8 bit
.I = 32 bit little-endian
.L = 64 bit little-endian
.U = prefix-encoded 32 bit unsigned number n:
0x00..0xdf → n.B
0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B
0x1fe0.. → 0xff n.I
```
## Error handling
Many of the buffer methods can throw an error. Out-of-memory or usage errors are best caught with an outer wrapper for larger parts of code. There's not much one can do after that, anyway.
On the other hand, you may want to catch some errors individually. Buffer methods need to receive the buffer object as the first argument. The Lua colon-syntax `obj:method()` does that implicitly. But to wrap a method with `pcall()`, the arguments need to be passed like this:
```lua
local ok, err = pcall(buf.encode, buf, obj);
if not ok then
-- Handle error in err
end
```
## FFI caveats
The string buffer library has been designed to work well together with the FFI library. But due to the low-level nature of the FFI library, some care needs to be taken:
First, please remember that FFI pointers are zero-indexed. The space returned by `buf:reserve()` and `buf:ref()` starts at the returned pointer and ends before `len` bytes after that.
I.e. the first valid index is `ptr[0]` and the last valid index is `ptr[len-1]`. If the returned length is zero, there's no valid index at all. The returned pointer may even be `NULL`.
The space pointed to by the returned pointer is only valid as long as the buffer is not modified in any way (neither append, nor consume, nor reset, etc.). The pointer is also not a GC anchor for the buffer object itself.
Buffer data is only guaranteed to be byte-aligned. Casting the returned pointer to a data type with higher alignment may cause unaligned accesses. It depends on the CPU architecture whether this is allowed or not (it's always OK on x86/x64 and mostly OK on other modern architectures).
FFI pointers or references do not count as GC anchors for an underlying object. E.g. an `array` allocated with `ffi.new()` is anchored by `buf:set(array, len)`, but not by `buf:set(array+offset, len)`. The addition of the offset creates a new pointer, even when the offset is zero. In this case, you need to make sure there's still a reference to the original array as long as its contents are in use by the buffer.
Even though each LuaJIT VM instance is single-threaded (but you can create multiple VMs), FFI data structures can be accessed concurrently. Be careful when reading/writing FFI cdata from/to buffers to avoid concurrent accesses or modifications. In particular, the memory referenced by `buf:set(cdata, len)` must not be modified while buffer readers are working on it. Shared, but read-only memory mappings of files are OK, but only if the file does not change.

79
doc/extensions/c-api.md Normal file
View File

@ -0,0 +1,79 @@
# Lua/C API Extensions
LuaJIT adds some extensions to the standard Lua/C API. The LuaJIT include directory must be in the compiler search path (`-I`*`path`*) to be able to include the required header for C code:
```c
#include "luajit.h"
// Or this for C++ code
#include "lua.hpp"
```
## `luaJIT_setmode(L, idx, mode)` — Control VM
This is a C API extension to allow control of the VM from C code. The full prototype of `LuaJIT_setmode` is:
```c
LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
```
The returned status is either success (`1`) or failure (`0`). The second argument is either `0` or a stack index (similar to the other Lua/C API functions).
The third argument specifies the mode, which is 'or'ed with a flag. The flag can be `LUAJIT_MODE_OFF` to turn a feature off, `LUAJIT_MODE_ON` to turn a feature on, or `LUAJIT_MODE_FLUSH` to flush cached code.
The following modes are defined:
### `luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)`
Turn the whole JIT compiler on or off or flush the whole cache of compiled code.
### `luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)` `luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)` `luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)`
This sets the mode for the function at the stack index `idx` or the parent of the calling function (`idx = 0`). It either enables JIT compilation for a function, disables it and flushes any already compiled code, or only flushes already compiled code. This applies recursively to all sub-functions of the function with `LUAJIT_MODE_ALLFUNC` or only to the sub-functions with `LUAJIT_MODE_ALLSUBFUNC`.
### `luaJIT_setmode(L, trace,` `  LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)`
Flushes the specified root trace and all of its side traces from the cache. The code for the trace will be retained as long as there are any other traces which link to it.
### `luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)`
This mode defines a wrapper function for calls to C functions. If called with `LUAJIT_MODE_ON`, the stack index at `idx` must be a `lightuserdata` object holding a pointer to the wrapper function. From now on, all C functions are called through the wrapper function. If called with `LUAJIT_MODE_OFF` this mode is turned off and all C functions are directly called.
The wrapper function can be used for debugging purposes or to catch and convert foreign exceptions. But please read the section on [C++ exception interoperability](./extensions#exceptions) first. Recommended usage can be seen in this C++ code excerpt:
```c++
#include <exception>
#include "lua.hpp"
// Catch C++ exceptions and convert them to Lua error messages.
// Customize as needed for your own exception classes.
static int wrap_exceptions(lua_State *L, lua_CFunction f) {
try {
// Call wrapped function and return result
return f(L);
}
catch (const char *s) {
// Catch and convert exceptions
lua_pushstring(L, s);
}
catch (std::exception& e) {
lua_pushstring(L, e.what());
}
catch (...) {
lua_pushliteral(L, "caught (...)");
}
// Rethrow as a Lua error
return lua_error(L);
}
static int myinit(lua_State *L) {
...
// Define wrapper function and enable it.
lua_pushlightuserdata(L, (void *)wrap_exceptions);
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
lua_pop(L, 1);
...
}
```
Note that you can only define **a single global wrapper function**, so be careful when using this mechanism from multiple C++ modules. Also note that this mechanism is not without overhead.

212
doc/extensions/index.md Normal file
View File

@ -0,0 +1,212 @@
# Extensions
LuaJIT is fully upwards-compatible with Lua 5.1. It supports all
[» standard Lua library functions](https://www.lua.org/manual/5.1/manual.html#5) and the full set of [» Lua/C API functions](https://www.lua.org/manual/5.1/manual.html#3).
LuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic loader level. This means you can compile a C module against the standard Lua headers and load the same shared library from either Lua or LuaJIT.
LuaJIT extends the standard Lua VM with new functionality and adds several extension modules. Please note, this page is only about *functional* enhancements and not about performance enhancements, such as the optimized VM, the faster interpreter or the JIT compiler.
## Extensions Modules
LuaJIT comes with several built-in extension modules:
### `bit.*` — Bitwise operations
LuaJIT supports all bitwise operations as defined by [» Lua BitOp](https://bitop.luajit.org):
``` lua
bit.tobit bit.tohex bit.bnot bit.band bit.bor bit.bxor
bit.lshift bit.rshift bit.arshift bit.rol bit.ror bit.bswap
```
This module is a LuaJIT built-in — you don't need to download or install Lua BitOp. The Lua BitOp site has full documentation for all [» Lua BitOp API functions](https://bitop.luajit.org/api.html). The FFI adds support for [64 bit bitwise operations](./ext_ffi_semantics#cdata_arith), using the same API functions.
Please make sure to `require` the module before using any of its functions:
```lua
local bit = require "bit";
```
An already installed Lua BitOp module is ignored by LuaJIT. This way you can use bit operations from both Lua and LuaJIT on a shared installation.
### `ffi.*` — FFI library
The [FFI library](./ext_ffi) allows calling external C functions and the use of C data structures from pure Lua code.
### `jit.*` — JIT compiler control
The functions in this module [control the behavior of the JIT compiler engine](./ext_jit).
### C API extensions
LuaJIT adds some [extra functions to the Lua/C API](./ext_c_api).
### Profiler
LuaJIT has an [integrated profiler](./ext_profiler).
## Enhanced Standard Library Functions
### `xpcall(f, err [,args...])` passes arguments
Unlike the standard implementation in Lua 5.1, `xpcall()` passes any arguments after the error function to the function which is called in a protected context.
### `load*()` handle UTF-8 source code
Non-ASCII characters are handled transparently by the Lua source code parser. This allows the use of UTF-8 characters in identifiers and strings. A UTF-8 BOM is skipped at the start of the source code.
### `load*()` add a mode parameter
As an extension from Lua 5.2, the functions `loadstring()`, `loadfile()` and (new) `load()` add an optional `mode` parameter.
The default mode string is `"bt"`, which allows loading of both source code and bytecode. Use `"t"` to allow only source code or `"b"` to allow only bytecode to be loaded.
By default, the `load*` functions generate the native bytecode format. For cross-compilation purposes, add `W` to the mode string to force the 32 bit format and `X` to force the 64 bit format. Add both to force the opposite format. Note that non-native bytecode generated by `load*` cannot be run, but can still be passed to `string.dump`.
### `tostring()` etc. canonicalize NaN and ±Inf
All number-to-string conversions consistently convert non-finite numbers to the same strings on all platforms. NaN results in `"nan"`, positive infinity results in `"inf"` and negative infinity results in `"-inf"`.
### `tonumber()` etc. use builtin string to number conversion
All string-to-number conversions consistently convert integer and floating-point inputs in decimal, hexadecimal and binary on all platforms. `strtod()` is *not* used anymore, which avoids numerous problems with poor C library implementations. The builtin conversion function provides full precision according to the IEEE-754 standard, it works independently of the current locale and it supports hex floating-point numbers (e.g. `0x1.5p-3`).
### `string.dump(f [,mode])` generates portable bytecode
An extra argument has been added to `string.dump()`. If set to `true` or to a string which contains the character `s`, 'stripped' bytecode without debug information is generated. This speeds up later bytecode loading and reduces memory usage. See also the [`-b` command line option](./running#opt_b).
The generated bytecode is portable and can be loaded on any architecture that LuaJIT supports. However, the bytecode compatibility versions must match. Bytecode only stays compatible within a major+minor version (x.y.aaa → x.y.bbb), except for development branches. Foreign bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
Note: `LJ_GC64` mode requires a different frame layout, which implies a different, incompatible bytecode format between 32 bit and 64 bit ports. This may be rectified in the future. In the meantime, use the `W` and X [modes of the `load*` functions](#load-add-a-mode-parameter) for cross-compilation purposes.
Due to VM hardening, bytecode is not deterministic. Add `d` to the mode string to dump it in a deterministic manner: identical source code always gives a byte-for-byte identical bytecode dump. This feature is mainly useful for reproducible builds.
### `table.new(narray, nhash)` allocates a pre-sized table
An extra library function `table.new()` can be made available via `require("table.new")`. This creates a pre-sized table, just like the C API equivalent `lua_createtable()`. This is useful for big tables if the final table size is known and automatic table resizing is too expensive.
### `table.clear(tab)` clears a table
An extra library function `table.clear()` can be made available via `require("table.clear")`. This clears all keys and values from a table, but preserves the allocated array/hash sizes. This is useful when a table, which is linked from multiple places, needs to be cleared and/or when recycling a table for use by the same context. This avoids managing backlinks, saves an allocation and the overhead of incremental array/hash part growth.
Please note, this function is meant for very specific situations. In most cases it's better to replace the (usually single) link with a new table and let the GC do its work.
### Enhanced PRNG for `math.random()`
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement `math.random()` and `math.randomseed()`. The quality of the PRNG results is much superior compared to the standard Lua implementation, which uses the platform-specific ANSI `rand()`.
The PRNG generates the same sequences from the same seeds on all platforms and makes use of all bits in the seed argument. `math.random()` without arguments generates 52 pseudo-random bits for every call. The result is uniformly distributed between 0.0 and 1.0. It's correctly scaled up and rounded for `math.random(n [,m])` to preserve uniformity.
Call `math.randomseed()` without any arguments to seed it from system entropy.
Important: Neither this nor any other PRNG based on the simplistic `math.random()` API is suitable for cryptographic use.
### `io.*` functions handle 64 bit file offsets
The file I/O functions in the standard `io.*` library handle 64 bit file offsets. In particular, this means it's possible to open files larger than 2 Gigabytes and to reposition or obtain the current file position for offsets beyond 2 GB (`fp:seek()` method).
### `debug.*` functions identify metamethods
`debug.getinfo()` and `lua_getinfo()` also return information about invoked metamethods. The `namewhat` field is set to `"metamethod"` and the `name` field has the name of the corresponding metamethod (e.g. `"__index"`).
## Fully Resumable VM
The LuaJIT VM is fully resumable. This means you can yield from a coroutine even across contexts, where this would not possible with the standard Lua 5.1 VM: e.g. you can yield across `pcall()` and `xpcall()`, across iterators and across metamethods.
## Extensions from Lua 5.2
LuaJIT supports some language and library extensions from Lua 5.2. Features that are unlikely to break existing code are unconditionally enabled:
- `goto` and `::labels::`.
- Hex escapes `'\x3F'` and `'\z'` escape in strings.
- `load(string|reader [, chunkname [,mode [,env]]])`.
- `loadstring()` is an alias for `load()`.
- `loadfile(filename [,mode [,env]])`.
- `math.log(x [,base])`.
- `string.rep(s, n [,sep])`.
- `string.format()`: `%q` reversible. `%s` checks `__tostring`. `%a` and `"%A` added.
- String matching pattern `%g` added.
- `io.read("*L")`.
- `io.lines()` and `file:lines()` process `io.read()` options.
- `os.exit(status|true|false [,close])`.
- `package.searchpath(name, path [, sep [, rep]])`.
- `package.loadlib(name, "*")`.
- `debug.getinfo()` returns `nparams` and `isvararg` for option `"u"`.
- `debug.getlocal()` accepts function instead of level.
- `debug.getlocal()` and `debug.setlocal()` accept negative indexes for varargs.
- `debug.getupvalue()` and `debug.setupvalue()` handle C functions.
- `debug.upvalueid()` and `debug.upvaluejoin()`.
- Lua/C API extensions: `lua_version()` `lua_upvalueid()` `lua_upvaluejoin()` `lua_loadx()` `lua_copy()` `lua_tonumberx()` `lua_tointegerx()` `luaL_fileresult()` `luaL_execresult()` `luaL_loadfilex()` `luaL_loadbufferx()` `luaL_traceback()` `luaL_setfuncs()` `luaL_pushmodule()` `luaL_newlibtable()` `luaL_newlib()` `luaL_testudata()` `luaL_setmetatable()`
- Command line option `-E`.
- Command line checks `__tostring` for errors.
Other features are only enabled, if LuaJIT is built with `-DLUAJIT_ENABLE_LUA52COMPAT`:
- `goto` is a keyword and not a valid variable name anymore.
- `break` can be placed anywhere. Empty statements (`;;`) are allowed.
- `__lt`, `__le` are invoked for mixed types.
- `__len` for tables. `rawlen()` library function.
- `pairs()` and `ipairs()` check for `__pairs` and `__ipairs`.
- `coroutine.running()` returns two results.
- `table.pack()` and `table.unpack()` (same as `unpack()`).
- `io.write()` and `file:write()` return file handle instead of `true`.
- `os.execute()` and `pipe:close()` return detailed exit status.
- `debug.setmetatable()` returns object.
- `debug.getuservalue()` and `debug.setuservalue()`.
- Remove `math.mod()`, `string.gfind()`.
- `package.searchers`.
- `module()` returns the module table.
Note: this provides only partial compatibility with Lua 5.2 at the
language and Lua library level. LuaJIT is API+ABI-compatible with
Lua 5.1, which prevents implementing features that would otherwise break
the Lua/C API and ABI (e.g. `_ENV`).
## Extensions from Lua 5.3
LuaJIT supports some extensions from Lua 5.3:
- Unicode escape `'\u{XX...}'` embeds the UTF-8 encoding in string literals.
- The argument table `arg` can be read (and modified) by `LUA_INIT` and `-e` chunks.
- `io.read()` and `file:read()` accept formats with or without a leading `*`.
- `assert()` accepts any type of error object.
- `table.move(a1, f, e, t [,a2])`.
- `coroutine.isyieldable()`.
- Lua/C API extensions: `lua_isyieldable()`
## C++ Exception Interoperability
LuaJIT has built-in support for interoperating with C++ exceptions. The
available range of features depends on the target platform and the
toolchain used to compile LuaJIT:
Platform | Compiler | Interoperability
----------------------------------|------------------|------------------
External frame unwinding | GCC, Clang, MSVC | **Full**
Internal frame unwinding + DWARF2 | GCC, Clang | **Limited**
Windows 64 bit | non-MSVC | **Limited**
Other platforms | Other compilers | **No**
**Full interoperability** means:
- C++ exceptions can be caught on the Lua side with `pcall()`, `lua_pcall()` etc.
- C++ exceptions will be converted to the generic Lua error `"C++ exception"`, unless you use the [C call wrapper](./ext_c_api#luajit_setmodel-idx-luajit_mode_wrapcfuncflag) feature.
- It's safe to throw C++ exceptions across non-protected Lua frames on the C stack. The contents of the C++ exception object pass through unmodified.
- Lua errors can be caught on the C++ side with `catch(...)`. The corresponding Lua error message can be retrieved from the Lua stack.
- Throwing Lua errors across C++ frames is safe. C++ destructors will be called.
**Limited interoperability** means:
- C++ exceptions can be caught on the Lua side with `pcall()`, `lua_pcall()` etc.
- C++ exceptions will be converted to the generic Lua error `"C++ exception"`, unless you use the [C call wrapper](./ext_c_api#luajit_setmodel-idx-luajit_mode_wrapcfuncflag) feature.
- C++ exceptions will be caught by non-protected Lua frames and are rethrown as a generic Lua error. The C++ exception object will be destroyed.
- Lua errors **cannot** be caught on the C++ side.
- Throwing Lua errors across C++ frames will **not** call C++ destructors.
**No interoperability** means:
- It's **not** safe to throw C++ exceptions across Lua frames.
- C++ exceptions **cannot** be caught on the Lua side.
- Lua errors **cannot** be caught on the C++ side.
- Throwing Lua errors across C++ frames will **not** call C++ destructors.

73
doc/extensions/jit.md Normal file
View File

@ -0,0 +1,73 @@
# `jit.*` Library
The functions in this built-in module control the behavior of the JIT compiler engine. Note that JIT-compilation is fully automatic — you probably won't need to use any of the following functions unless you have special needs.
### `jit.on()` `jit.off()`
Turns the whole JIT compiler on (default) or off.
These functions are typically used with the command line options `-j on` or `-j off`.
### `jit.flush()`
Flushes the whole cache of compiled code.
### `jit.on(func|true [,true|false])` `jit.off(func|true [,true|false])` `jit.flush(func|true [,true|false])`
`jit.on` enables JIT compilation for a Lua function (this is the default).
`jit.off` disables JIT compilation for a Lua function and flushes any already compiled code from the code cache.
`jit.flush` flushes the code, but doesn't affect the enable/disable status.
The current function, i.e. the Lua function calling this library function, can also be specified by passing `true` as the first argument.
If the second argument is `true`, JIT compilation is also enabled, disabled or flushed recursively for all sub-functions of a function. With `false` only the sub-functions are affected.
The `jit.on` and `jit.off` functions only set a flag which is checked when the function is about to be compiled. They do not trigger immediate compilation.
Typical usage is `jit.off(true, true)` in the main chunk of a module to turn off JIT compilation for the whole module for debugging purposes.
### `jit.flush(tr)`
Flushes the root trace, specified by its number, and all of its side traces from the cache. The code for the trace will be retained as long as there are any other traces which link to it.
### `status, ... = jit.status()`
Returns the current status of the JIT compiler. The first result is either `true` or `false` if the JIT compiler is turned on or off. The remaining results are strings for CPU-specific features and enabled optimizations.
### `jit.version`
Contains the LuaJIT version string.
### `jit.version_num`
Contains the version number of the LuaJIT core. Version xx.yy.zz is represented by the decimal number xxyyzz. **DEPRECATED after the switch to [» rolling releases](https://luajit.org/status.html#release). zz is frozen at 99.**
### `jit.os`
Contains the target OS name: "Windows", "Linux", "OSX", "BSD", "POSIX" or "Other".
### `jit.arch`
Contains the target architecture name: "x86", "x64", "arm", "arm64", "arm64be", "ppc", "mips", "mipsel", "mips64", "mips64el", "mips64r6", "mips64r6el".
## `jit.opt.*` — JIT compiler optimization control
This submodule provides the backend for the `-O` command line option.
You can also use it programmatically, e.g.:
```lua
jit.opt.start(2); -- same as -O2
jit.opt.start("-dce");
jit.opt.start("hotloop=10", "hotexit=2");
```
Unlike in LuaJIT 1.x, the module is built-in and **optimization is turned on by default!** It's no longer necessary to run `require("jit.opt").start()`, which was one of the ways to enable optimization.
## `jit.util.*` — JIT compiler introspection
This submodule holds functions to introspect the bytecode, generated traces, the IR and the generated machine code. The functionality provided by this module is still in flux and therefore undocumented.
The debug modules `-jbc`, `-jv` and `-jdump` make extensive use of these functions. Please check out their source code, if you want to know more.

159
doc/extensions/profiler.md Normal file
View File

@ -0,0 +1,159 @@
# Profiler
LuaJIT has an integrated statistical profiler with very low overhead. It allows sampling the currently executing stack and other parameters in regular intervals.
The integrated profiler can be accessed from three levels:
- The [bundled high-level profiler](#high-level-profiler), invoked by the [`-jp`](#-jpoptionsoutput) command line option.
- A [low-level Lua API](#ll_lua_api) to control the profiler.
- A [low-level C API](#ll_c_api) to control the profiler.
## High-Level Profiler
The bundled high-level profiler offers basic profiling functionality. It generates simple textual summaries or source code annotations. It can be accessed with the [`-jp`](#-jpoptionsoutput) command line option or from Lua code by loading the underlying `jit.p` module.
To cut to the chase - run this to get a CPU usage profile by function name:
```sh
luajit -jp myapp.lua
```
It's *not* a stated goal of the bundled profiler to add every possible option or to cater for special profiling needs. The low-level profiler APIs are documented below. They may be used by third-party authors to implement advanced functionality, e.g. IDE integration or graphical profilers.
Note: Sampling works for both interpreted and JIT-compiled code. The results for JIT-compiled code may sometimes be surprising. LuaJIT heavily optimizes and inlines Lua code - there's no simple one-to-one correspondence between source code lines and the sampled machine code.
### `-jp=[options[,output]]`
The `-jp` command line option starts the high-level profiler. When the application run by the command line terminates, the profiler stops and writes the results to `stdout` or to the specified `output` file.
The `options` argument specifies how the profiling is to be performed:
- `f` - Stack dump: function name, otherwise module:line. This is the default mode.
- `F` - Stack dump: ditto, but dump module:name.
- `l` - Stack dump: module:line.
- `<number>` - stack dump depth (callee ← caller). Default: 1.
- `-<number>` - Inverse stack dump depth (caller → callee).
- `s` - Split stack dump after first stack level. Implies depth  2 or depth  -2.
- `p` - Show full path for module names.
- `v` - Show VM states.
- `z` - Show [zones](#jit_zone).
- `r` - Show raw sample counts. Default: show percentages.
- `a` - Annotate excerpts from source code files.
- `A` - Annotate complete source code files.
- `G` - Produce raw output suitable for graphical tools.
- `m<number>` - Minimum sample percentage to be shown. Default: 3%.
- `i<number>` - Sampling interval in milliseconds. Default: 10ms. Note: The actual sampling precision is OS-dependent.
The default output for `-jp` is a list of the most CPU consuming spots in the application. Increasing the stack dump depth with (say) `-jp=2` may help to point out the main callers or callees of hotspots. But sample aggregation is still flat per unique stack dump.
To get a two-level view (split view) of callers/callees, use `-jp=s` or `-jp=-s`. The percentages shown for the second level are relative to the first level.
To see how much time is spent in each line relative to a function, use `-jp=fl`.
To see how much time is spent in different VM states or [zones](#jitzone--zones), use `-jp=v` or `-jp=z`.
Combinations of `v/z` with `f/F/l` produce two-level views, e.g. `-jp=vf` or `-jp=fv`. This shows the time spent in a VM state or zone vs. hotspots. This can be used to answer questions like "Which time-consuming functions are only interpreted?" or "What's the garbage collector overhead for a specific function?".
Multiple options can be combined - but not all combinations make sense, see above. E.g. `-jp=3si4m1` samples three stack levels deep in 4ms intervals and shows a split view of the CPU consuming functions and their callers with a 1% threshold.
Source code annotations produced by `-jp=a` or `-jp=A` are always flat and at the line level. Obviously, the source code files need to be readable by the profiler script.
The high-level profiler can also be started and stopped from Lua code with:
```lua
require "jit.p".start(options, output);
...
require "jit.p".stop();
```
### `jit.zone` - Zones
Zones can be used to provide information about different parts of an application to the high-level profiler. E.g. a game could make use of an `"AI"` zone, a `"PHYS"` zone, etc. Zones are hierarchical, organized as a stack.
The `jit.zone` module needs to be loaded explicitly:
```lua
local zone = require "jit.zone";
```
- `zone("name")` pushes a named zone to the zone stack.
- `zone()` pops the current zone from the zone stack and returns its name.
- `zone:get()` returns the current zone name or `nil`.
- `zone:flush()` flushes the zone stack.
To show the time spent in each zone use `-jp=z`. To show the time spent relative to hotspots use e.g. `-jp=zf` or `-jp=fz`.
## Low-level Lua API
The `jit.profile` module gives access to the low-level API of the profiler from Lua code. This module needs to be loaded explicitly:
```lua
local profile = require "jit.profile";
```
This module can be used to implement your own higher-level profiler. A typical profiling run starts the profiler, captures stack dumps in the profiler callback, adds them to a hash table to aggregate the number of samples, stops the profiler and then analyzes all captured stack dumps. Other parameters can be sampled in the profiler callback, too. But it's important not to spend too much time in the callback, since this may skew the statistics.
### `profile.start(mode, cb)`: Start profiler
This function starts the profiler. The `mode` argument is a string
holding options:
- `f` - Profile with precision down to the function level.
- `l` - Profile with precision down to the line level.
- `i<number>` - Sampling interval in milliseconds (default 10ms). Note: The actual sampling precision is OS-dependent.
The `cb` argument is a callback function which is called with three arguments: `(thread, samples, vmstate)`. The callback is called on a separate coroutine, the `thread` argument is the state that holds the stack to sample for profiling. Note: do *not* modify the stack of that state or call functions on it.
`samples` gives the number of accumulated samples since the last callback (usually 1).
`vmstate` holds the VM state at the time the profiling timer triggered. This may or may not correspond to the state of the VM when the profiling callback is called. The state is either `'N'` native (compiled) code, `'I'` interpreted code, `'C'` C code, `'G'` the garbage collector, or `'J'` the JIT compiler.
### `profile.stop()`: Stop profiler
This function stops the profiler.
### `dump = profile.dumpstack([thread,] fmt, depth)`: Dump stack
This function allows taking stack dumps in an efficient manner. It returns a string with a stack dump for the `thread` (coroutine), formatted according to the `fmt` argument:
- `p`: Preserve the full path for module names. Otherwise, only the file name is used.
- `f`: Dump the function name if it can be derived. Otherwise, use module:line.
- `F`: Ditto, but dump module:name.
- `l`: Dump module:line.
- `Z`: Zap the following characters for the last dumped frame.
- All other characters are added verbatim to the output string.
The `depth` argument gives the number of frames to dump, starting at the topmost frame of the thread. A negative number dumps the frames in inverse order.
The first example prints a list of the current module names and line numbers of up to 10 frames in separate lines. The second example prints semicolon-separated function names for all frames (up to 100) in inverse order:
```lua
print(profile.dumpstack(thread, "l\n", 10));
print(profile.dumpstack(thread, "lZ;", -100));
```
## Low-level C API
The profiler can be controlled directly from C code, e.g. for use by IDEs. The declarations are in `"luajit.h"` (see [Lua/C API](./ext_c_api) extensions).
### `luaJIT_profile_start(L, mode, cb, data)` - Start profiler
This function starts the profiler. [See above](#profilestartmode-cb-start-profiler) for a description of the `mode` argument.
The `cb` argument is a callback function with the following declaration:
```c
typedef void (*luaJIT_profile_callback)(void *data, lua_State *L, int samples, int vmstate);
```
`data` is available for use by the callback. `L` is the state that holds the stack to sample for profiling. Note: do *not* modify this stack or call functions on this stack - use a separate coroutine for this purpose. [See above](#profilestartmode-cb-start-profiler) for a description of `samples` and `vmstate`.
### `luaJIT_profile_stop(L)` - Stop profiler
This function stops the profiler.
### `p = luaJIT_profile_dumpstack(L, fmt, depth, len)` - Dump stack
This function allows taking stack dumps in an efficient manner. [See above](#dump--profiledumpstackthread-fmt-depth-dump-stack) for a description of `fmt` and `depth`.
This function returns a `const char *` pointing to a private string buffer of the profiler. The `int *len` argument returns the length of the output string. The buffer is overwritten on the next call and deallocated when the profiler stops. You either need to consume the content immediately or copy it for later use.

240
doc/ffi/api.md Normal file
View File

@ -0,0 +1,240 @@
# `ffi.*` API Functions
This page describes the API functions provided by the FFI library in
detail. It's recommended to read through the
[introduction](./ext_ffi) and the [FFI
tutorial](./ext_ffi_tutorial) first.
## Glossary
- **cdecl**: An abstract C type declaration (a Lua string).
- **ctype**: A C type object. This is a special kind of **cdata** returned by `ffi.typeof()`. It serves as a **cdata** [constructor](#ffi_new) when called.
- **cdata**: A C data object. It holds a value of the corresponding **ctype**.
- **ct**: A C type specification which can be used for most of the API functions. Either a **cdecl**, a **ctype** or a **cdata** serving as a template type.
- **cb**: A callback object. This is a C data object holding a special function pointer. Calling this function from C code runs an associated Lua function.
- **VLA**: A variable-length array is declared with a `?` instead of the number of elements, e.g. `"int[?]"`. The number of elements (`nelem`) must be given when it's [created](#ffi_new).
- **VLS**: A variable-length struct is a `struct` C type where the last element is a **VLA**. The same rules for declaration and creation apply.
## Declaring and Accessing External Symbols
External symbols must be declared first and can then be accessed by indexing a [C library namespace](./ext_ffi_semantics#clib), which automatically binds the symbol to a specific library.
### `ffi.cdef(def)`
Adds multiple C declarations for types or external symbols (named variables or functions). `def` must be a Lua string. It's recommended to use the syntactic sugar for string arguments as follows:
```lua
ffi.cdef [[
// Declare a struct and typedef
typedef struct foo { int a, b; } foo_t;
// Declare an external C function
int dofoo(foo_t *f, int n);
]]
```
The contents of the string (the part in green above) must be a sequence of [C declarations](./ext_ffi_semantics#clang), separated by semicolons. The trailing semicolon for a single declaration may be omitted.
Please note, that external symbols are only *declared*, but they are *not bound* to any specific address, yet. Binding is achieved with C library namespaces (see below).
C declarations are not passed through a C pre-processor, yet. No pre-processor tokens are allowed, except for `#pragma pack`. Replace `#define` in existing C header files with `enum`, `static const` or `typedef` and/or pass the files through an external C pre-processor (once). Be careful not to include unneeded or redundant declarations from unrelated header files.
### `ffi.C`
This is the default C library namespace — note the uppercase `'C'`. It binds to the default set of symbols or libraries on the target system. These are more or less the same as a C compiler would offer by default, without specifying extra link libraries.
On POSIX systems, this binds to symbols in the default or global namespace. This includes all exported symbols from the executable and any libraries loaded into the global namespace. This includes at least `libc`, `libm`, `libdl` (on Linux), `libgcc` (if compiled with GCC), as well as any exported symbols from the Lua/C API provided by LuaJIT itself.
On Windows systems, this binds to symbols exported from the `*.exe`, the `lua51.dll` (i.e. the Lua/C API provided by LuaJIT itself), the C runtime library LuaJIT was linked with (`msvcrt*.dll`), `kernel32.dll`, `user32.dll` and `gdi32.dll`.
### `clib = ffi.load(name [,global])`
This loads the dynamic library given by `name` and returns a new C library namespace which binds to its symbols. On POSIX systems, if `global` is `true`, the library symbols are loaded into the global namespace, too.
If `name` is a path, the library is loaded from this path. Otherwise `name` is canonicalized in a system-dependent way and searched in the default search path for dynamic libraries:
On POSIX systems, if the name contains no dot, the extension `.so` is appended. Also, the `lib` prefix is prepended if necessary. So `ffi.load "z"` looks for `"libz.so"` in the default shared library search path.
On Windows systems, if the name contains no dot, the extension `.dll` is appended. So `ffi.load "ws2_32"` looks for `"ws2_32.dll"` in the default DLL search path.
## Creating cdata Objects
The following API functions create cdata objects (`type()` returns `"cdata"`). All created cdata objects are [garbage collected](./ext_ffi_semantics#gc).
### `cdata = ffi.new(ct [,nelem] [,init...])` `cdata = `*`ctype`*`([nelem,] [init...])`
Creates a cdata object for the given `ct`. VLA/VLS types require the `nelem` argument. The second syntax uses a ctype as a constructor and is otherwise fully equivalent.
The cdata object is initialized according to the [rules for initializers](./ext_ffi_semantics#init), using the optional `init` arguments. Excess initializers cause an error.
Performance notice: if you want to create many objects of one kind, parse the cdecl only once and get its ctype with `ffi.typeof()`. Then use the ctype as a constructor repeatedly.
Please note, that an anonymous `struct` declaration implicitly creates a new and distinguished ctype every time you use it for `ffi.new()`. This is probably **not** what you want, especially if you create more than one cdata object. Different anonymous `structs` are not considered assignment-compatible by the C standard, even though they may have the same fields! Also, they are considered different types by the JIT-compiler, which may cause an excessive number of traces. It's strongly suggested to either declare a named `struct` or `typedef` with `ffi.cdef()` or to create a single ctype object for an anonymous `struct` with `ffi.typeof()`.
### `ctype = ffi.typeof(ct)`
Creates a ctype object for the given `ct`.
This function is especially useful to parse a cdecl only once and then use the resulting ctype object as a [constructor](#ffi_new).
### `cdata = ffi.cast(ct, init)`
Creates a scalar cdata object for the given `ct`. The cdata object is initialized with `init` using the "cast" variant of the [C type conversion rules](./ext_ffi_semantics#convert).
This functions is mainly useful to override the pointer compatibility checks or to convert pointers to addresses or vice versa.
### `ctype = ffi.metatype(ct, metatable)`
Creates a ctype object for the given `ct` and associates it with a metatable. Only `struct`/`union` types, complex numbers and vectors are allowed. Other types may be wrapped in a `struct`, if needed.
The association with a metatable is permanent and cannot be changed afterwards. Neither the contents of the `metatable` nor the contents of an `__index` table (if any) may be modified afterwards. The associated metatable automatically applies to all uses of this type, no matter how the objects are created or where they originate from. Note that predefined operations on types have precedence (e.g. declared field names cannot be overridden).
All standard Lua metamethods are implemented. These are called directly, without shortcuts, and on any mix of types. For binary operations, the left operand is checked first for a valid ctype metamethod. The `__gc` metamethod only applies to `struct`/`union` types and performs an implicit [`ffi.gc()`](#ffi_gc) call during creation of an instance.
### `cdata = ffi.gc(cdata, finalizer)`
Associates a finalizer with a pointer or aggregate cdata object. The cdata object is returned unchanged.
This function allows safe integration of unmanaged resources into the automatic memory management of the LuaJIT garbage collector. Typical usage:
```lua
local p = ffi.gc(ffi.C.malloc(n), ffi.C.free);
...
-- Last reference to p is gone.
p = nil;
-- GC will eventually run finalizer: ffi.C.free(p)
```
A cdata finalizer works like the `__gc` metamethod for userdata objects: when the last reference to a cdata object is gone, the associated finalizer is called with the cdata object as an argument. The finalizer can be a Lua function or a cdata function or cdata function pointer. An existing finalizer can be removed by setting a `nil` finalizer, e.g. right before explicitly deleting a resource:
```lua
-- Manually free the memory.
ffi.C.free(ffi.gc(p, nil));
```
## C Type Information
The following API functions return information about C types. They are most useful for inspecting cdata objects.
### `size = ffi.sizeof(ct [,nelem])`
Returns the size of `ct` in bytes. Returns `nil` if the size is not known (e.g. for `"void"` or function types). Requires `nelem` for VLA/VLS types, except for cdata objects.
### `align = ffi.alignof(ct)`
Returns the minimum required alignment for `ct` in bytes.
### `ofs [,bpos,bsize] = ffi.offsetof(ct, field)`
Returns the offset (in bytes) of `field` relative to the start of `ct`, which must be a `struct`. Additionally returns the position and the field size (in bits) for bit fields.
### `status = ffi.istype(ct, obj)`
Returns `true` if `obj` has the C type given by `ct`. Returns `false`
otherwise.
C type qualifiers (`const` etc.) are ignored. Pointers are checked with the standard pointer compatibility rules, but without any special treatment for `void *`. If `ct` specifies a `struct`/`union`, then a pointer to this type is accepted, too. Otherwise the types must match exactly.
Note: this function accepts all kinds of Lua objects for the `obj` argument, but always returns `false` for non-cdata objects.
## Utility Functions
### `err = ffi.errno([newerr])`
Returns the error number set by the last C function call which indicated an error condition. If the optional `newerr` argument is present, the error number is set to the new value and the previous value is returned.
This function offers a portable and OS-independent way to get and set the error number. Note that only *some* C functions set the error number. And it's only significant if the function actually indicated an error condition (e.g. with a return value of `-1` or `NULL`). Otherwise, it may or may not contain any previously set value.
You're advised to call this function only when needed and as close as possible after the return of the related C function. The `errno` value is preserved across hooks, memory allocations, invocations of the JIT compiler and other internal VM activity. The same applies to the value returned by `GetLastError()` on Windows, but you need to declare and call it yourself.
### `str = ffi.string(ptr [,len])`
Creates an interned Lua string from the data pointed to by `ptr`.
If the optional argument `len` is missing, `ptr` is converted to a `"char *"` and the data is assumed to be zero-terminated. The length of the string is computed with `strlen()`.
Otherwise `ptr` is converted to a `"void *"` and `len` gives the length of the data. The data may contain embedded zeros and need not be byte-oriented (though this may cause endianess issues).
This function is mainly useful to convert (temporary) `"const char *"` pointers returned by C functions to Lua strings and store them or pass them to other functions expecting a Lua string. The Lua string is an (interned) copy of the data and bears no relation to the original data area anymore. Lua strings are 8 bit clean and may be used to hold arbitrary, non-character data.
Performance notice: it's faster to pass the length of the string, if it's known. E.g. when the length is returned by a C call like `sprintf()`.
### `ffi.copy(dst, src, len)` `ffi.copy(dst, str)`
Copies the data pointed to by `src` to `dst`. `dst` is converted to a `"void *"` and `src` is converted to a `"const void *"`.
In the first syntax, `len` gives the number of bytes to copy. Caveat: if `src` is a Lua string, then `len` must not exceed `#src+1`.
In the second syntax, the source of the copy must be a Lua string. All bytes of the string *plus a zero-terminator* are copied to `dst` (i.e. `#src+1` bytes).
Performance notice: `ffi.copy()` may be used as a faster (inlinable) replacement for the C library functions `memcpy()`, `strcpy()` and `strncpy()`.
### `ffi.fill(dst, len [,c])`
Fills the data pointed to by `dst` with `len` constant bytes, given by `c`. If `c` is omitted, the data is zero-filled.
Performance notice: `ffi.fill()` may be used as a faster (inlinable) replacement for the C library function `memset(dst, c, len)`. Please note the different order of arguments!
## Target-specific Information
### `status = ffi.abi(param)`
Returns `true` if `param` (a Lua string) applies for the target ABI (Application Binary Interface). Returns `false` otherwise. The following parameters are currently defined:
Parameter | Description
----------|------------
32bit | 32 bit architecture
64bit | 64 bit architecture
le | Little-endian architecture
be | Big-endian architecture
fpu | Target has a hardware FPU
softfp | softfp calling conventions
hardfp | hardfp calling conventions
eabi | EABI variant of the standard ABI
win | Windows variant of the standard ABI
pauth | Pointer authentication ABI
uwp | Universal Windows Platform
gc64 | 64 bit GC references
### `ffi.os`
Contains the target OS name. Same contents as [`jit.os`](./ext_jit#jit_os).
### `ffi.arch`
Contains the target architecture name. Same contents as [`jit.arch`](./ext_jit#jit_arch).
## Methods for Callbacks
The C types for [callbacks](./ext_ffi_semantics#callback) have some extra methods:
### `cb:free()`
Free the resources associated with a callback. The associated Lua function is unanchored and may be garbage collected. The callback function pointer is no longer valid and must not be called again (it may be reused by a subsequently created callback).
### `cb:set(func)`
Associate a new Lua function with a callback. The C type of the callback and the callback function pointer are unchanged.
This method is useful to dynamically switch the receiver of callbacks without creating a new callback each time and registering it again (e.g. with a GUI library).
## Extended Standard Library Functions
The following standard library functions have been extended to work with cdata objects:
### `n = tonumber(cdata)`
Converts a number cdata object to a `double` and returns it as a Lua number. This is particularly useful for boxed 64 bit integer values. Caveat: this conversion may incur a precision loss.
### `s = tostring(cdata)`
Returns a string representation of the value of 64 bit integers (**`"`**`nnn`**`LL"`** or **`"`**`nnn`**`ULL"`**) or complex numbers (**`"`**`re±im`**`i"`**). Otherwise returns a string representation of the C type of a ctype object (**`"ctype<`**`type`**`>"`**) or a cdata object (**`"cdata<`**`type`**`>: `**`address"`), unless you override it with a `__tostring` metamethod (see [`ffi.metatype()`](#ffi_metatype)).
### `iter, obj, start = pairs(cdata)` `iter, obj, start = ipairs(cdata)`
Calls the `__pairs` or `__ipairs` metamethod of the corresponding ctype.
## Extensions to the Lua Parser
The parser for Lua source code treats numeric literals with the suffixes `LL` or `ULL` as signed or unsigned 64 bit integers. Case doesn't matter, but uppercase is recommended for readability. It handles decimal (`42LL`), hexadecimal (`0x2aLL`) and binary (`0b101010LL`) literals.
The imaginary part of complex numbers can be specified by suffixing number literals with `i` or `I`, e.g. `12.5i`. Caveat: you'll need to use `1i` to get an imaginary part with the value one, since `i` itself still refers to a variable named `i`.

138
doc/ffi/index.md Normal file
View File

@ -0,0 +1,138 @@
# FFI Library
The FFI library allows **calling external C functions** and **using C data structures** from pure Lua code.
The FFI library largely obviates the need to write tedious manual Lua/C bindings in C. No need to learn a separate binding language — **it parses plain C declarations!** 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.
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 data structures from Lua code is on par with the code a C compiler would generate. Calls to C functions can be inlined in JIT-compiled code, unlike calls to functions bound via the classic Lua/C API.
This page gives a short introduction to the usage of the FFI library. *Please use the FFI sub-topics in the navigation bar to learn more.*
## Motivating Example: Calling External C Functions
It's really easy to call an external C library function:
```lua
local ffi = require "ffi"; -- (1)
ffi.cdef [[
int printf(const char *fmt, ...);
]]; -- (2)
ffi.C.printf("Hello %s!", "world"); -- (3)
```
So, let's pick that apart:
1. Load the FFI library.
2. Add a C declaration for the function. The
part inside the double-brackets (in green) is just standard C syntax.
3. Call the named C function — Yes, it's that
simple!
Actually, what goes on behind the scenes is far from simple: (3) makes use of the standard C library namespace `ffi.C`. Indexing this namespace with a symbol name (`"printf"`) automatically binds it to the standard C library. The result is a special kind of object which, when called, runs the `printf` function. The arguments passed to this function are automatically converted from Lua objects to the corresponding C types.
Ok, so maybe the use of `printf()` wasn't such a spectacular example. You could have done that with `io.write()` and `string.format()`, too. But you get the idea ...
So here's something to pop up a message box on Windows:
```lua
local ffi = require "ffi";
ffi.cdef [[
int MessageBoxA(void *w, const char *txt, const char *cap, int type);
]];
ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0);
```
Bing! Again, that was far too easy, no?
Compare this with the effort required to bind that function using the classic Lua/C API: create an extra C file, add a C function that retrieves and checks the argument types passed from Lua and calls the actual C function, add a list of module functions and their names, add a `luaopen_*` 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!
## Motivating Example: Using C Data Structures
The FFI library allows you to create and access C data structures. Of course, the main use for this is for interfacing with C functions. But they can be used stand-alone, too.
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.
Here's a sketch of a library that operates on color images, plus a simple benchmark. First, the plain Lua version:
```lua
local floor = math.floor;
local function image_ramp_green(n)
local img = {};
local f = 255 / (n - 1);
for i = 1, n do
img[i] = { r = 0, g = floor((i - 1) * f), b = 0, a = 255 };
end
return img;
end
local function image_to_gray(img, n)
for i = 1, n do
local val = floor(0.3 * img[i].red + 0.59 * img[i].green + 0.11 * img[i].blue);
img[i].r = val;
img[i].g = val;
img[i].b = val;
end
end
local N = 400 * 400;
local img = image_ramp_green(N);
for i = 1, 1000 do
image_to_gray(img, N);
end
```
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 ...
And here's the FFI version. The modified parts have been marked:
```lua
local ffi = require "ffi"; -- (1)
ffi.cdef [[
typedef struct { uint8_t r, g, b, a; } rgba_pixel;
]];
local function image_ramp_green(n)
local img = ffi.new("rgba_pixel[?]", n); -- (2)
local f = 255 / (n - 1);
for i = 0, n - 1 do -- (3)
img[i].g = i * f; -- (4)
img[i].a = 255;
end
return img;
end
local function image_to_grey(img, n)
for i = 0, n - 1 do -- (3)
local val = 0.3 * img[i].r + 0.59 * img[i].g + 0.11 * img[i].b; -- (5)
img[i].r = val; img[i].g = val; img[i].b = val
end
end
local N = 400 * 400;
local img = image_ramp_green(N);
for i = 1, 1000 do
image_to_grey(img, N);
end
```
Ok, so that wasn't too difficult:
1. First, load the FFI library and declare the low-level data type. Here we choose a `struct` which holds four byte fields, one for each component of a 4x8 bit RGBA pixel.
2. Creating the data structure with `ffi.new()` is straightforward — the `'?'` is a placeholder for the number of elements of a variable-length array.
3. C arrays are zero-based, so the indexes have to run from `0` to `n-1`. One might want to allocate one more element instead to simplify converting legacy code.
4. Since `ffi.new()` zero-fills the array by default, we only need to set the green and the alpha fields.
5. The calls to `math.floor()` 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.
Now let's have a look at the impact of the changes: first, memory consumption for the image is down from 22 Megabytes to 640 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 Megabytes in plain Lua (on x64).
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).
The avid reader may notice that converting the pure Lua version over to use array indexes for the colors (`[1]` instead of `.red`, `[2]` instead of `.green` 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.
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 functions, especially I/O functions, without undue conversion penalties.

479
doc/ffi/semantics.md Normal file
View File

@ -0,0 +1,479 @@
# FFI Semantics
This page describes the detailed semantics underlying the FFI library and its interaction with both Lua and C code.
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 language semantics.
Please don't be overwhelmed by the contents of this page — this is a reference and you may need to consult it, if in doubt. It doesn't hurt to skim this page, but most of the semantics "just work" as you'd expect them to work. It should be straightforward to write applications using the LuaJIT FFI for developers with a C or C++ background.
## C Language Support
The FFI library has a built-in C parser with a minimal memory footprint. It's used by the [ffi.\* library functions](./ext_ffi_api) to declare C types or external symbols.
Its only purpose is to parse C declarations, as found e.g. in C header files. Although it does evaluate constant expressions, it's *not* a C compiler. The body of `inline` C function definitions is simply ignored.
Also, this is *not* a validating C parser. It expects and accepts correctly formed C declarations, but it may choose to ignore bad declarations or show rather generic error messages. If in doubt, please check the input against your favorite C compiler.
The C parser complies to the **C99 language standard** plus the following extensions:
- The `'\e'` escape in character and string literals.
- The C99/C++ boolean type, declared with the keywords `bool` or `_Bool`.
- Complex numbers, declared with the keywords `complex` or `_Complex`.
- Two complex number types: `complex` (aka `complex double`) and `complex float`.
- Vector types, declared with the GCC `mode` or `vector_size` attribute.
- Unnamed ('transparent') `struct`/`union` fields inside a `struct`/`union`.
- Incomplete `enum` declarations, handled like incomplete `struct` declarations.
- Unnamed `enum` fields inside a `struct`/`union`. This is similar to a scoped C++ `enum`, except that declared constants are visible in the global namespace, too.
- Scoped `static const` declarations inside a `struct`/`union` (from C++).
- Zero-length arrays (`[0]`), empty `struct`/`union`, variable-length arrays (VLA, `[?]`) and variable-length structs (VLS, with a trailing VLA).
- C++ reference types (`int &x`).
- Alternate GCC keywords with '`__`', e.g. `__const__`.
- GCC `__attribute__` with the following attributes: `aligned`, `packed`, `mode`, `vector_size`, `cdecl`, `fastcall`, `stdcall`, `thiscall`.
- The GCC `__extension__` keyword and the GCC `__alignof__` operator.
- GCC `__asm__("symname")` symbol name redirection for function declarations.
- MSVC keywords for fixed-length types: `__int8`, `__int16`, `__int32` and `__int64`.
- MSVC `__cdecl`, `__fastcall`, `__stdcall`, `__thiscall`, `__ptr32`, `__ptr64`, `__declspec(align(n))` and `#pragma pack`.
- All other GCC/MSVC-specific attributes are ignored.
The following C types are predefined by the C parser (like a `typedef`, except re-declarations will be ignored):
- Vararg handling: `va_list`, `__builtin_va_list`, `__gnuc_va_list`.
- From `<stddef.h>`: `ptrdiff_t`, `size_t`, `wchar_t`.
- From `<stdint.h>`: `int8_t`, `int16_t`, `int32_t`, `int64_t`, `uint8_t`, `uint16_t`, `uint32_t`, `uint64_t`, `intptr_t`, `uintptr_t`.
- From `<unistd.h>` (POSIX): `ssize_t`.
You're encouraged to use these types in preference to compiler-specific extensions or target-dependent standard types. E.g. `char` differs in signedness and `long` differs in size, depending on the target architecture and platform ABI.
The following C features are **not** supported:
- A declaration must always have a type specifier; it doesn't default to an `int` type.
- Old-style empty function declarations (K&R) are not allowed. All C functions must have a proper prototype declaration. A function declared without parameters (`int foo();`) is treated as a function taking zero arguments, like in C++.
- The `long double` C type is parsed correctly, but there's no support for the related conversions, accesses or arithmetic operations.
- Wide character strings and character literals are not supported.
- [See below](#status) for features that are currently not implemented.
## C Type Conversion Rules
### Conversions from C types to Lua objects
These conversion rules apply for *read accesses* to C types: indexing pointers, arrays or `struct`/`union` types; reading external variables or constant values; retrieving return values from C calls:
Input | Output | Conversion
----------------------|------------------|----
`int8_t`, `int16_t` | number | →<sup>sign-ext</sup> `int32_t``double`
`uint8_t`, `uint16_t` | number | →<sup>zero-ext</sup> `int32_t``double`
`int32_t`, `uint32_t` | number | → `double`
`int64_t`, `uint64_t` | 64 bit int cdata | boxed value
`double`, `float` | number | → `double`
`bool` | boolean | 0 → `false`, otherwise `true`
`enum` | enum cdata | boxed value
Complex number | complex cdata | boxed value
Vector | vector cdata | boxed value
Pointer | pointer cdata | boxed value
Array | reference cdata | boxed reference
`struct`/`union` | reference cdata | boxed reference
Bitfields are treated like their underlying type.
Reference types are dereferenced *before* a conversion can take place — the conversion is applied to the C type pointed to by the reference.
### Conversions from Lua objects to C types
These conversion rules apply for *write accesses* to C types: indexing pointers, arrays or `struct`/`union` types; initializing cdata objects; casts to C types; writing to external variables; passing arguments to C calls:
Input | Output | Conversion
--------------|-------------------------|---------
number | `double` | →
boolean | `bool` | `false` → 0, `true` → 1
nil | `(void *)` | `NULL`
lightuserdata | `(void *)` | lightuserdata address →
userdata | `(void *)` | userdata payload →
io.\* file | `(void *)` | get FILE \* handle →
string | `enum` | match against `enum` constant
string | `int8_t[]`, `uint8_t[]` | copy string data + zero-byte
string | `const char[]` | string data →
function | C function type | [create callback](#callback) →
table | Array | [table initializer](#init_table)
table | `struct`/`union` | [table initializer](#init_table)
cdata | C type | cdata payload →
If the result type of this conversion doesn't match the C type of the destination, the [conversion rules between C types](#convert_between) are applied.
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 variables under the Lua language semantics. If you want to call a function with a reference parameter, you need to explicitly pass a one-element array.
### Conversions between C types
These conversion rules are more or less the same as the standard C conversion rules. Some rules only apply to casts, or require pointer or type compatibility:
Input | Output | Conversion
------------------|----------------------------|------------------
Signed integer | Integer | →<sup>narrow\ or\ sign-extend</sup>
Unsigned integer | Integer | →<sup>narrow\ or\ zero-extend</sup>
Integer | `double`, `float` | →<sup>round</sup>
`double`, `float` | `(u)int8_t`, `(u)int16_t` | →<sup>trunc</sup> `int32_t`<sup>narrow</sup>
`double`, `float` | `(u)int32_t`, `(u)int64_t` | →<sup>trunc</sup>
`double`, `float` | `float`, `double` | →<sup>round</sup>
Number | `bool` | n == 0 → 0, otherwise 1
`bool` | Number | `false` → 0, `true` → 1
Complex number | Number | convert real part
Number | Complex number | convert real part, imag = 0
Complex number | Complex number | convert real and imag part
Number | Vector | convert scalar and replicate
Vector | Vector | copy (same size)
`struct`/`union` | Pointer | take base address (compat)
Array | Pointer | take base address (compat)
Function | Function pointer | take function address
Number | Pointer | convert via `uintptr_t` (cast)
Pointer | Pointer | convert address (compat/cast)
Pointer | Integer | convert address (cast)
Array | Integer | convert base address (cast)
Array | Array | copy (compat)
`struct`/`union` | `struct`/`union` | copy (identical type)
Bitfields or `enum` types are treated like their underlying type.
Conversions not listed above will raise an error. E.g. it's not possible to convert a pointer to a complex number or vice versa.
### Conversions for vararg C function arguments
The following default conversion rules apply when passing Lua objects to the variable argument part of vararg C functions:
Input | Output | Conversion
-----------------------|--------------------------|------------
number | `double` | →
boolean | `bool` | `false` → 0, `true` → 1
nil | `(void *)` | `NULL`
userdata | `(void *)` | userdata payload →
lightuserdata | `(void *)` | lightuserdata address →
string | `const char *` | string data →
`float` cdata | `double` | →
Array cdata | Element pointer | take base address
`struct`/`union` cdata | `struct`/`union` pointer | take base address
Function cdata | Function pointer | take function address
Any other cdata | C type | no conversion
To pass a Lua object, other than a cdata object, as a specific type, you need to override the conversion rules: create a temporary cdata object with a constructor or a cast and initialize it with the value to pass:
Assuming `x` is a Lua number, here's how to pass it as an integer to a vararg function:
```lua
ffi.cdef[[
int printf(const char *fmt, ...);
]];
ffi.C.printf("integer value: %d\n", ffi.new("int", x));
```
If you don't do this, the default Lua number → `double` conversion rule applies. A vararg C function expecting an integer will see a garbled or uninitialized value.
Note: this is the only place where creating a boxed scalar number type is actually useful. **Never use `ffi.new("int")`, `ffi.new("float")` etc. anywhere else!**
Ditto for `ffi.cast()`. Explicitly boxing scalars **does not** improve performance or force `int` or `float` arithmetic! It just adds costly boxing, unboxing and conversions steps. And it may lead to surprise results, because [cdata arithmetic on scalar numbers](#cdata_arith) is always performed on 64 bit integers.
## Initializers
Creating a cdata object with [`ffi.new()`](./ext_ffi_api#ffi_new) or the equivalent constructor syntax always initializes its contents, too. Different rules apply, depending on the number of optional initializers and the C types involved:
- If no initializers are given, the object is filled with zero bytes.
- Scalar types (numbers and pointers) accept a single initializer. The Lua object is [converted to the scalar C type](#convert_fromlua).
- Valarrays (complex numbers and vectors) are treated like scalars when a single initializer is given. Otherwise they are treated like regular arrays.
- Aggregate types (arrays and structs) accept either a single cdata initializer of the same type (copy constructor), a single [table initializer](#init_table), or a flat list of initializers.
- The elements of an array are initialized, starting at index zero. If a single initializer is given for an array, it's repeated for all remaining elements. This doesn't happen if two or more initializers are given: all remaining uninitialized elements are filled with zero bytes.
- Byte arrays may also be initialized with a Lua string. This copies the whole string plus a terminating zero-byte. The copy stops early only if the array has a known, fixed size.
- The fields of a `struct` are initialized in the order of their declaration. Uninitialized fields are filled with zero bytes.
- Only the first field of a `union` can be initialized with a flat initializer.
- Elements or fields which are aggregates themselves are initialized with a *single* initializer, but this may be a table initializer or a compatible aggregate.
- Excess initializers cause an error.
## Table Initializers
The following rules apply if a Lua table is used to initialize an Array or a `struct`/`union`:
- If the table index `[0]` is non-`nil`, then the table is assumed to be zero-based. Otherwise it's assumed to be one-based.
- Array elements, starting at index zero, are initialized one-by-one with the consecutive table elements, starting at either index `[0]` or `[1]`. This process stops at the first `nil` table element.
- If exactly one array element was initialized, it's repeated for all the remaining elements. Otherwise all remaining uninitialized elements are filled with zero bytes.
- The above logic only applies to arrays with a known fixed size. A VLA is only initialized with the element(s) given in the table. Depending on the use case, you may need to explicitly add a `NULL` or `0` terminator to a VLA.
- A `struct`/`union` can be initialized in the order of the declaration of its fields. Each field is initialized with consecutive table elements, starting at either index `[0]` or `[1]`. This process stops at the first `nil` table element.
- Otherwise, if neither index `[0]` nor `[1]` is present, a `struct`/`union` is initialized by looking up each field name (as a string key) in the table. Each non-`nil` value is used to initialize the corresponding field.
- Uninitialized fields of a `struct` are filled with zero bytes, except for the trailing VLA of a VLS.
- Initialization of a `union` stops after one field has been initialized. If no field has been initialized, the `union` is filled with zero bytes.
- Elements or fields which are aggregates themselves are initialized with a *single* initializer, but this may be a nested table initializer (or a compatible aggregate).
- Excess initializers for an array cause an error. Excess initializers for a `struct`/`union` are ignored. Unrelated table entries are ignored, too.
Example:
```lua
local ffi = require "ffi";
ffi.cdef [[
struct foo { int a, b; };
union bar { int i; double d; };
struct nested { int x; struct foo y; };
]];
ffi.new("int[3]", {}); --> 0, 0, 0
ffi.new("int[3]", { 1 }); --> 1, 1, 1
ffi.new("int[3]", { 1, 2 }); --> 1, 2, 0
ffi.new("int[3]", { 1, 2, 3 }); --> 1, 2, 3
ffi.new("int[3]", { [0] = 1 }); --> 1, 1, 1
ffi.new("int[3]", { [0] = 1, 2 }); --> 1, 2, 0
ffi.new("int[3]", { [0] = 1, 2, 3 }); --> 1, 2, 3
ffi.new("int[3]", { [0] = 1, 2, 3, 4 }); --> error: too many initializers
ffi.new("struct foo", {}); --> a = 0, b = 0
ffi.new("struct foo", { 1 }); --> a = 1, b = 0
ffi.new("struct foo", { 1, 2 }); --> a = 1, b = 2
ffi.new("struct foo", { [0] = 1, 2 }); --> a = 1, b = 2
ffi.new("struct foo", { b = 2 }); --> a = 0, b = 2
ffi.new("struct foo", { a = 1, b = 2, c = 3 }); --> a = 1, b = 2 'c' is ignored
ffi.new("union bar", {}); --> i = 0, d = 0.0
ffi.new("union bar", { 1 }); --> i = 1, d = ?
ffi.new("union bar", { [0] = 1, 2 }); --> i = 1, d = ? '2' is ignored
ffi.new("union bar", { d = 2 }); --> i = ?, d = 2.0
ffi.new("struct nested", { 1, { 2, 3 } }); --> x = 1, y.a = 2, y.b = 3
ffi.new("struct nested", { x = 1, y = { 2, 3 } }); --> x = 1, y.a = 2, y.b = 3
```
## Operations on cdata Objects
All standard Lua operators can be applied to cdata objects or a mix of a cdata object and another Lua object. The following list shows the predefined operations.
Reference types are dereferenced *before* performing each of the operations below — the operation is applied to the C type pointed to by the reference.
The predefined operations are always tried first before deferring to a metamethod or index table (if any) for the corresponding ctype (except for `__new`). An error is raised if the metamethod lookup or index table lookup fails.
### Indexing a cdata object
- **Indexing a pointer/array**: a cdata pointer/array can be indexed by a cdata number or a Lua number. The element address is computed as the base address plus the number value multiplied by the element size in bytes. A read access loads the element value and [converts it to a Lua object](#convert_tolua). A write access [converts a Lua object to the element type](#convert_fromlua) and stores the converted value to the element. An error is raised if the element size is undefined or a write access to a constant element is attempted.
- **Dereferencing a `struct`/`union` field**: a cdata `struct`/`union` or a pointer to a `struct`/`union` can be dereferenced by a string key, giving the field name. The field address is computed as the base address plus the relative offset of the field. A read access loads the field value and [converts it to a Lua object](#convert_tolua). A write access [converts a Lua object to the field type](#convert_fromlua) and stores the converted value to the field. An error is raised if a write access to a constant `struct`/`union` or a constant field is attempted. Scoped enum constants or static constants are treated like a constant field.
- **Indexing a complex number**: a complex number can be indexed either by a cdata number or a Lua number with the values 0 or 1, or by the strings `"re"` or `"im"`. A read access loads the real part (`[0]`, `.re`) or the imaginary part (`[1]`, `.im`) part of a complex number and [converts it to a Lua number](#convert_tolua). The sub-parts of a complex number are immutable — assigning to an index of a complex number raises an error. Accessing out-of-bound indexes returns unspecified results, but is guaranteed not to trigger memory access violations.
- **Indexing a vector**: a vector is treated like an array for indexing purposes, except the vector elements are immutable — assigning to an index of a vector raises an error.
A ctype object can be indexed with a string key, too. The only predefined operation is reading scoped constants of `struct`/`union` types. All other accesses defer to the corresponding metamethods or index tables (if any).
Note: since there's (deliberately) no address-of operator, a cdata object holding a value type is effectively immutable after initialization. The JIT compiler benefits from this fact when applying certain optimizations.
As a consequence, the *elements* of complex numbers and vectors are immutable. But the elements of an aggregate holding these types *may* be modified, of course. I.e. you cannot assign to `foo.c.im`, but you can assign a (newly created) complex number to `foo.c`.
The JIT compiler implements strict aliasing rules: accesses to different types do **not** alias, except for differences in signedness (this applies even to `char` pointers, unlike C99). Type punning through unions is explicitly detected and allowed.
### Calling a cdata object
- **Constructor**: a ctype object can be called and used as a [constructor](./ext_ffi_api#ffi_new). This is equivalent to `ffi.new(ct, ...)`, unless a `__new` metamethod is defined. The `__new` metamethod is called with the ctype object plus any other arguments passed to the constructor. Note that you have to use `ffi.new` inside the metamethod, since calling `ct(...)` would cause infinite recursion.
- **C function call**: a cdata function or cdata function pointer can be called. The passed arguments are [converted to the C types](#convert_fromlua) of the parameters given by the function declaration. Arguments passed to the variable argument part of vararg C function use [special conversion rules](#convert_vararg). This C function is called and the return value (if any) is [converted to a Lua object](#convert_tolua). On Windows/x86 systems, `__stdcall` functions are automatically detected, and a function declared as `__cdecl` (the default) is silently fixed up after the first call.
### Arithmetic on cdata objects
- **Pointer arithmetic**: a cdata pointer/array and a cdata number or a Lua number can be added or subtracted. The number must be on the right-hand side for a subtraction. The result is a pointer of the same type with an address plus or minus the number value multiplied by the element size in bytes. An error is raised if the element size is undefined.
- **Pointer difference**: two compatible cdata pointers/arrays can be subtracted. The result is the difference between their addresses, divided by the element size in bytes. An error is raised if the element size is undefined or zero.
- **64 bit integer arithmetic**: the standard arithmetic operators (`+ - * / % ^` and unary minus) can be applied to two cdata numbers, or a cdata number and a Lua number. If one of them is an `uint64_t`, the other side is converted to an `uint64_t` and an unsigned arithmetic operation is performed. Otherwise, both sides are converted to an `int64_t` and a signed arithmetic operation is performed. The result is a boxed 64 bit cdata object. If one of the operands is an `enum` and the other operand is a string, the string is converted to the value of a matching `enum` constant before the above conversion. These rules ensure that 64 bit integers are "sticky". Any expression involving at least one 64 bit integer operand results in another one. The undefined cases for the division, modulo and power operators return `2LL ^ 63` or `2ULL ^ 63`. You'll have to explicitly convert a 64 bit integer to a Lua number (e.g. for regular floating-point calculations) with `tonumber()`. But note this may incur a precision loss.
- **64 bit bitwise operations**: the rules for 64 bit arithmetic operators apply analogously. Unlike the other `bit.*` operations, `bit.tobit()` converts a cdata number via `int64_t` to `int32_t` and returns a Lua number. For `bit.band()`, `bit.bor()` and `bit.bxor()`, the conversion to `int64_t` or `uint64_t` applies to *all* arguments, if *any* argument is a cdata number. For all other operations, only the first argument is used to determine the output type. This implies that a cdata number as a shift count for shifts and rotates is accepted, but that alone does *not* cause a cdata number output.
### Comparisons of cdata objects
- **Pointer comparison**: two compatible cdata pointers/arrays can be compared. The result is the same as an unsigned comparison of their addresses. `nil` is treated like a `NULL` pointer, which is compatible with any other pointer type.
- **64 bit integer comparison**: two cdata numbers, or a cdata number and a Lua number can be compared with each other. If one of them is an `uint64_t`, the other side is converted to an `uint64_t` and an unsigned comparison is performed. Otherwise, both sides are converted to an `int64_t` and a signed comparison is performed. If one of the operands is an `enum` and the other operand is a string, the string is converted to the value of a matching `enum` constant before the above conversion.
- **Comparisons for equality/inequality** never raise an error. Even incompatible pointers can be compared for equality by address. Any other incompatible comparison (also with non-cdata objects) treats the two sides as unequal.
### cdata objects as table keys
Lua tables may be indexed by cdata objects, but this doesn't provide any useful semantics — **cdata objects are unsuitable as table keys!**
A cdata object is treated like any other garbage-collected object and is hashed and compared by its address for table indexing. Since there's no interning for cdata value types, the same value may be boxed in different cdata objects with different addresses. Thus, `t[1LL+1LL]` and `t[2LL]` usually **do not** point to the same hash slot, and they certainly **do not** point to the same hash slot as `t[2]`.
It would seriously drive up implementation complexity and slow down the common case, if one were to add extra handling for by-value hashing and comparisons to Lua tables. Given the ubiquity of their use inside the VM, this is not acceptable.
There are three viable alternatives, if you really need to use cdata z objects as keys:
- If you can get by with the precision of Lua numbers (52 bits), then use `tonumber()` on a cdata number or combine multiple fields of a cdata aggregate to a Lua number. Then use the resulting Lua number as a key when indexing tables. One obvious benefit: `t[tonumber(2LL)]` **does** point to the same slot as `t[2]`.
- Otherwise, use either `tostring()` on 64 bit integers or complex numbers or combine multiple fields of a cdata aggregate to a Lua string (e.g. with [`ffi.string()`](./ext_ffi_api#ffi_string)). Then use the resulting Lua string as a key when indexing tables.
- Create your own specialized hash table implementation using the C types provided by the FFI library, just like you would in C code. Ultimately, this may give much better performance than the other alternatives or what a generic by-value hash table could possibly provide.
## Parameterized Types
To facilitate some abstractions, the two functions [`ffi.typeof`](./ext_ffi_api#ffi_typeof) and [`ffi.cdef`](./ext_ffi_api#ffi_cdef) support parameterized types in C declarations. Note: none of the other API functions taking a cdecl allow this.
Any place you can write a **`typedef` name**, an **identifier** or a **number** in a declaration, you can write `$` (the dollar sign) instead. These placeholders are replaced in order of appearance with the arguments following the cdecl string:
```lua
-- Declare a struct with a parameterized field type and name:
ffi.cdef([[
typedef struct { $ $; } foo_t;
]], type1, name1);
-- Anonymous struct with dynamic names:
local bar_t = ffi.typeof("struct { int $, $; }", name1, name2);
-- Derived pointer type:
local bar_ptr_t = ffi.typeof("$ *", bar_t);
-- Parameterized dimensions work even where a VLA won't work:
local matrix_t = ffi.typeof("uint8_t[$][$]", width, height);
```
Caveat: this is *not* simple text substitution! A passed ctype or cdata object is treated like the underlying type, a passed string is considered an identifier and a number is considered a number. You must not mix this up: e.g. passing `"int"` as a string doesn't work in place of a type, you'd need to use `ffi.typeof("int")` instead.
The main use for parameterized types are libraries implementing abstract data types ([» example](https://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8)), similar to what can be achieved with C++ template metaprogramming. Another use case are derived types of anonymous structs, which avoids pollution of the global struct namespace.
Please note that parameterized types are a nice tool and indispensable for certain use cases. But you'll want to use them sparingly in regular code, e.g. when all types are actually fixed.
## Garbage Collection of cdata Objects
All explicitly (`ffi.new()`, `ffi.cast()` etc.) or implicitly (accessors) created cdata objects are garbage collected. You need to ensure to retain valid references to cdata objects somewhere on a Lua stack, an upvalue or in a Lua table while they are still in use. Once the last reference to a cdata object is gone, the garbage collector will automatically free the memory used by it (at the end of the next GC cycle).
Please note, that pointers themselves are cdata objects, however they are **not** followed by the garbage collector. So e.g. if you assign a cdata array to a pointer, you must keep the cdata object holding the array alive as long as the pointer is still in use:
```lua
ffi.cdef[[
typedef struct { int *a; } foo_t;
]];
local s = ffi.new("foo_t", ffi.new("int[10]")); -- WRONG!
local a = ffi.new("int[10]"); -- OK
local s = ffi.new("foo_t", a);
-- Now do something with 's', but keep 'a' alive until you're done.
```
Similar rules apply for Lua strings which are implicitly converted to `"const char *"`: 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 been overwritten. Note that *string literals* are automatically kept alive as long as the function containing it (actually its prototype) is not garbage collected.
Objects which are passed as an argument to an external C function are kept alive until the call returns. So it's generally safe to create temporary cdata objects in argument lists. This is a common idiom for [passing specific C types to vararg functions](#convert_vararg).
Memory areas returned by C functions (e.g. from `malloc()`) must be manually managed, of course (or use [`ffi.gc()`](./ext_ffi_api#ffi_gc)). Pointers to cdata objects are indistinguishable from pointers returned by C functions (which is one of the reasons why the GC cannot follow them).
## Callbacks
The LuaJIT FFI automatically generates special callback functions whenever a Lua function is converted to a C function pointer. This associates the generated callback function pointer with the C type of the function pointer and the Lua function object (closure).
This can happen implicitly due to the usual conversions, e.g. when passing a Lua function to a function pointer argument. Or, you can use `ffi.cast()` to explicitly cast a Lua function to a C function pointer.
Currently, only certain C function types can be used as callback functions. Neither C vararg functions nor functions with pass-by-value aggregate argument or result types are supported. There are no restrictions on the kind of Lua functions that can be called from the callback — no checks for the proper number of arguments are made. The return value of the Lua function will be converted to the result type, and an error will be thrown for invalid conversions.
It's allowed to throw errors across a callback invocation, but it's not advisable in general. Do this only if you know the C function, that called the callback, copes with the forced stack unwinding and doesn't leak resources.
One thing that's not allowed, is to let an FFI call into a C function get JIT-compiled, which in turn calls a callback, calling into Lua again. Usually this attempt is caught by the interpreter first and the C function is blacklisted for compilation.
However, this heuristic may fail under specific circumstances: e.g. a message polling function might not run Lua callbacks right away and the call gets JIT-compiled. If it later happens to call back into Lua (e.g. a rarely invoked error callback), you'll get a VM PANIC with the message `"bad callback"`. Then you'll need to manually turn off JIT-compilation with [`jit.off()`](./ext_jit#jit_onoff_func) for the surrounding Lua function that invokes such a message polling function (or similar).
### Callback resource handling
Callbacks take up resources — you can only have a limited number of them at the same time (500 - 1000, depending on the architecture). The associated Lua functions are anchored to prevent garbage collection, too.
**Callbacks due to implicit conversions are permanent!** There is no way to guess their lifetime, since the C side might store the function pointer for later use (typical for GUI toolkits). The associated resources cannot be reclaimed until termination:
```lua
ffi.cdef [[
typedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l);
int EnumWindows(WNDENUMPROC func, intptr_t l);
]];
-- Implicit conversion to a callback via function pointer argument.
local count = 0;
ffi.C.EnumWindows(function(hwnd, l)
count = count + 1;
return true;
end, 0);
-- The callback is permanent and its resources cannot be reclaimed!
-- Ok, so this may not be a problem, if you do this only once.
```
Note: this example shows that you *must* properly declare `__stdcall` callbacks on Windows/x86 systems. The calling convention cannot be automatically detected, unlike for `__stdcall` calls *to* Windows functions.
For some use cases, it's necessary to free up the resources or to dynamically redirect callbacks. Use an explicit cast to a C function pointer and keep the resulting cdata object. Then use the [`cb:free()`](./ext_ffi_api#callback_free) or [`cb:set()`](./ext_ffi_api#callback_set) methods on the cdata object:
```lua
-- Explicitly convert to a callback via cast.
local count = 0;
local cb = ffi.cast("WNDENUMPROC", function(hwnd, l)
count = count + 1;
return true;
end);
-- Pass it to a C function.
ffi.C.EnumWindows(cb, 0);
-- EnumWindows doesn't need the callback after it returns, so free it.
cb:free();
-- The callback function pointer is no longer valid and its resources
-- will be reclaimed. The created Lua closure will be garbage collected.
```
### Callback performance
**Callbacks are slow!** First, the C to Lua transition itself has an unavoidable cost, similar to a `lua_call()` or `lua_pcall()`. Argument and result marshalling add to that cost. And finally, neither the C compiler nor LuaJIT can inline or optimize across the language barrier and hoist repeated computations out of a callback function.
Do not use callbacks for performance-sensitive work: e.g. consider a numerical integration routine which takes a user-defined function to integrate over. It's a bad idea to call a user-defined Lua function from C code millions of times. The callback overhead will be absolutely detrimental for performance.
It's considerably faster to write the numerical integration routine itself in Lua — the JIT compiler will be able to inline the user-defined function and optimize it together with its calling context, with very competitive performance.
As a general guideline: **use callbacks only when you must**, because of existing C APIs. E.g. callback performance is irrelevant for a GUI application, which waits for user input most of the time, anyway.
For new designs **avoid push-style APIs**: a C function repeatedly calling a callback for each result. Instead, **use pull-style APIs**: call a C function repeatedly to get a new result. Calls from Lua to C via the FFI are much faster than the other way round. Most well-designed libraries already use pull-style APIs (read/write, get/put).
## C Library Namespaces
A C library namespace is a special kind of object which allows access to the symbols contained in shared libraries or the default symbol namespace. The default [`ffi.C`](./ext_ffi_api#ffi_C) namespace is automatically created when the FFI library is loaded. C library namespaces for specific shared libraries may be created with the [`ffi.load()`](./ext_ffi_api#ffi_load) API function.
Indexing a C library namespace object with a symbol name (a Lua string) automatically binds it to the library. First, the symbol type is resolved — it must have been declared with [`ffi.cdef`](./ext_ffi_api#ffi_cdef). Then the symbol address is resolved by searching for the symbol name in the associated shared libraries or the default symbol namespace. Finally, the resulting binding between the symbol name, the symbol type and its address is cached. Missing symbol declarations or nonexistent symbol names cause an error.
This is what happens on a **read access** for the different kinds of
symbols:
- External functions: a cdata object with the type of the function and its address is returned.
- External variables: the symbol address is dereferenced and the loaded value is [converted to a Lua object](#convert_tolua) and returned.
- Constant values (`static const` or `enum` constants): the constant is [converted to a Lua object](#convert_tolua) and returned.
This is what happens on a **write access**:
- External variables: the value to be written is [converted to the C type](#convert_fromlua) of the variable and then stored at the symbol address.
- Writing to constant variables or to any other symbol type causes an error, like any other attempted write to a constant location.
C library namespaces themselves are garbage collected objects. If the last reference to the namespace object is gone, the garbage collector will eventually release the shared library reference and remove all memory associated with the namespace. Since this may trigger the removal of the shared library from the memory of the running process, it's generally *not safe* to use function cdata objects obtained from a library if the namespace object may be unreferenced.
Performance notice: the JIT compiler specializes to the identity of namespace objects and to the strings used to index it. This effectively turns function cdata objects into constants. It's not useful and actually counter-productive to explicitly cache these function objects, e.g. `local strlen = ffi.C.strlen`. OTOH, it *is* useful to cache the namespace itself, e.g. `local C = ffi.C`.
## No Hand-holding!
The FFI library has been designed as **a low-level library**. The goal is to interface with C code and C data types with a minimum of overhead. This means **you can do anything you can do from C**: access all memory, overwrite anything in memory, call machine code at any memory address and so on.
The FFI library provides **no memory safety**, unlike regular Lua code. It will happily allow you to dereference a `NULL` pointer, to access arrays out of bounds or to misdeclare C functions. If you make a mistake, your application might crash, just like equivalent C code would.
This behavior is inevitable, since the goal is to provide full interoperability with C code. Adding extra safety measures, like bounds checks, would be futile. There's no way to detect misdeclarations of C functions, since shared libraries only provide symbol names, but no type information. Likewise, there's no way to infer the valid range of indexes for a returned pointer.
Again: the FFI library is a low-level library. This implies it needs to be used with care, but it's flexibility and performance often outweigh this concern. If you're a C or C++ developer, it'll be easy to apply your existing knowledge. OTOH, writing code for the FFI library is not for the faint of heart and probably shouldn't be the first exercise for someone with little experience in Lua, C or C++.
As a corollary of the above, the FFI library is **not safe for use by untrusted Lua code**. If you're sandboxing untrusted Lua code, you definitely don't want to give this code access to the FFI library or to *any* cdata object (except 64 bit integers or complex numbers). Any properly engineered Lua sandbox needs to provide safety wrappers for many of the standard Lua library functions — similar wrappers need to be written for high-level operations on FFI data types, too.
## Current Status
The initial release of the FFI library has some limitations and is missing some features. Most of these will be fixed in future releases.
[C language support](#clang) is currently incomplete:
- C declarations are not passed through a C pre-processor, yet.
- The C parser is able to evaluate most constant expressions commonly found in C header files. However, it doesn't handle the full range of C expression semantics and may fail for some obscure constructs.
- `static const` declarations only work for integer types up to 32 bits. Neither declaring string constants nor floating-point constants is supported.
- Packed `struct` bitfields that cross container boundaries are not implemented.
- Native vector types may be defined with the GCC `mode` or `vector_size` attribute. But no operations other than loading, storing and initializing them are supported, yet.
- The `volatile` type qualifier is currently ignored by compiled code.
- [`ffi.cdef`](./ext_ffi_api#ffi_cdef) silently ignores most re-declarations. Note: avoid re-declarations which do not conform to C99. The implementation will eventually be changed to perform strict checks.
The JIT compiler already handles a large subset of all FFI operations. It automatically falls back to the interpreter for unimplemented operations (you can check for this with the [`-jv`](./running#opt_j) command line option). The following operations are currently not compiled and may exhibit suboptimal performance, especially when used in inner loops:
- Vector operations.
- Table initializers.
- Initialization of nested `struct`/`union` types.
- Non-default initialization of VLA/VLS or large C types (\> 128 bytes or \> 16 array elements).
- Bitfield initializations.
- Pointer differences for element sizes that are not a power of two.
- Calls to C functions with aggregates passed or returned by value.
- Calls to ctype metamethods which are not plain functions.
- ctype `__newindex` tables and non-string lookups in ctype `__index` tables.
- `tostring()` for cdata types.
- Calls to `ffi.cdef()`, `ffi.load()` and `ffi.metatype()`.
Other missing features:
- Arithmetic for `complex` numbers.
- Passing structs by value to vararg C functions.
- [C++ exception interoperability](./extensions#exceptions) does not extend to C functions called via the FFI, if the call is compiled.

232
doc/ffi/tutorial.md Normal file
View File

@ -0,0 +1,232 @@
# FFI Tutorial
This page is intended to give you an overview of the features of the FFI library by presenting a few use cases and guidelines.
This page makes no attempt to explain all of the FFI library, though. You'll want to have a look at the [ffi.* API function reference](./ext_ffi_api) and the [FFI semantics](./ext_ffi_semantics) to learn more.
## Loading the FFI Library
The FFI library is built into LuaJIT by default, but it's not loaded and initialized by default. The suggested way to use the FFI library is to add the following to the start of every Lua file that needs one of its functions:
```lua
local ffi = require "ffi";
```
Please note, this doesn't define an `ffi` variable in the table of globals — you really need to use the local variable. The `require` function ensures the library is only loaded once.
Note: If you want to experiment with the FFI from the interactive prompt of the command line executable, omit the `local`, as it doesn't preserve local variables across lines.
## Accessing Standard System Functions
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:
```lua
local ffi = require "ffi";
ffi.cdef[[
void Sleep(int ms);
int poll(struct pollfd *fds, unsigned long nfds, int timeout);
]]; -- (1)
local sleep;
if ffi.os == "Windows" then -- (2)
function sleep(s) -- (3)
ffi.C.Sleep(s * 1000); -- (4)
end
else
function sleep(s)
ffi.C.poll(nil, 0, s*1000) -- (5)
end
end
for i=1,160 do
io.write ".";
io.flush();
sleep(0.01); -- (6)
end
io.write "\n";
```
Here's the step-by-step explanation:
1. 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.
2. The difficulty we're facing here, is that there are different standards to choose from. Windows has a simple `Sleep()` function. On other systems there are a variety of functions available to achieve sub-second sleeps, but with no clear consensus. Thankfully `poll()` can be used for this task, too, and it's present on most non-Windows systems. The check for `ffi.os` makes sure we use the Windows-specific function only on Windows systems.
3. 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.
4. A more subtle point is that we defined our `sleep()` 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 leaves it a Lua number, which is a floating-point value. Alas, the `Sleep()` function only accepts an integer value. Luckily for us, the FFI library automatically performs the conversion when calling the function (truncating the FP value towards zero, like in C). <br> *Some readers will notice that `Sleep()` is part of `KERNEL32.DLL` and is also a `stdcall` function. So how can this possibly work? The FFI library provides the `ffi.C` default C library namespace, which allows calling functions from the default set of libraries, like a C compiler would. Also, the FFI library automatically detects `stdcall` functions, so you don't need to declare them as such.*
5. The `poll()` function takes a couple more arguments we're not going to use. You can simply use `nil` to pass a `NULL` pointer and `0` for the `nfds` parameter. Please note, that the number `0` *does not convert to a pointer value*, unlike in C++. You really have to pass pointers to pointer arguments and numbers to number arguments. <br> *The page on [FFI semantics](./ext_ffi_semantics) has all of the gory details about [conversions between Lua objects and C types](./ext_ffi_semantics#convert). For the most part you don't have to deal with this, as it's performed automatically and it's carefully designed to bridge the semantic differences between Lua and C.*
6. Now that we have defined our own `sleep()` 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. :-)
## Accessing the zlib Compression Library
The following code shows how to access the [» zlib](https://zlib.net/) compression library from Lua code. We'll define two convenience wrapper functions that take a string and compress or uncompress it to another string:
```lua
local ffi = require "ffi";
ffi.cdef [[
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);
]]; -- (1)
local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z"); -- (2)
local function compress(txt)
local n = zlib.compressBound(#txt); -- (3)
local buf = ffi.new("uint8_t[?]", n);
local buflen = ffi.new("unsigned long[1]", n); -- (4)
local res = zlib.compress2(buf, buflen, txt, #txt, 9);
assert(res == 0);
return ffi.string(buf, buflen[0]); -- (5)
end
local function uncompress(comp, n) -- (6)
local buf = ffi.new("uint8_t[?]", n);
local buflen = ffi.new("unsigned long[1]", n);
local res = zlib.uncompress(buf, buflen, comp, #comp);
assert(res == 0);
return ffi.string(buf, buflen[0]);
end
-- Simple test code (7)
local txt = string.rep("abcd", 1000);
print("Uncompressed size: ", #txt);
local c = compress(txt);
print("Compressed size: ", #c);
local txt2 = uncompress(c, #txt);
assert(txt2 == txt);
```
Here's the step-by-step explanation:
1. 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 predefined fixed-size integer types, while still adhering to the zlib API/ABI.
2. This loads the zlib shared library. On POSIX systems, it's named `libz.so` and usually comes pre-installed. Since `ffi.load()` automatically adds any missing standard prefixes/suffixes, we can simply load the `"z"` library. On Windows it's named `zlib1.dll` and you'll have to download it first from the [» zlib site](https://zlib.net/). The check for `ffi.os` makes sure we pass the right name to `ffi.load()`.
3. First, the maximum size of the compression buffer is obtained by calling the `zlib.compressBound` function with the length of the uncompressed string. The next line allocates a byte buffer of this size. The `[?]` in the type specification indicates a variable-length array (VLA). The actual number of elements of this array is given as the 2nd argument to `ffi.new()`.
4. This may look strange at first, but have a look at the declaration of the `compress2` 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 actual length that was used. <br> In C you'd pass in the address of a local variable (`&buflen`). But since there's no address-of operator in Lua, we'll just pass in a one-element array. Conveniently, it can be initialized with the maximum buffer size in one step. Calling the actual `zlib.compress2` function is then straightforward.
5. We want to return the compressed data as a Lua string, so we'll use `ffi.string()`. It needs a pointer to the start of the data and the actual length. The length has been returned in the `buflen` array, so we'll just get it from there. <br> *Note that since the function returns now, the `buf` and `buflen` variables will eventually be garbage collected. This is fine, because `ffi.string()` has copied the contents to a newly created (interned) Lua string. If you plan to call this function lots of times, consider reusing the buffers and/or handing back the results in buffers instead of strings. This will reduce the overhead for garbage collection and string interning.*
6. The `uncompress` functions does the exact opposite of the `compress` function. The compressed data doesn't include the size of the original string, so this needs to be passed in. Otherwise, no surprises here.
7. 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. <br> One major advantage of the LuaJIT FFI is that you are now able to write those wrappers *in Lua*. And at a fraction of the time it would cost you to create an extra C module using the Lua/C API. Many of the simpler C functions can probably be used directly from your Lua code, without any wrappers. <br> *Side note: the zlib API uses the `long` type for passing lengths and sizes around. But all those zlib functions actually only deal with 32 bit values. This is an unfortunate choice for a public API, but may be explained by zlib's history — we'll just have to deal with it.*
First, you should know that a `long` is a 64 bit type e.g. on POSIX/x64 systems, but a 32 bit type on Windows/x64 and on 32 bit systems. Thus a `long` result can be either a plain Lua number or a boxed 64 bit integer cdata object, depending on the target system.
Ok, so the `ffi.*` functions generally accept cdata objects wherever you'd want to use a number. That's why we get a away with passing `n` to `ffi.string()` above. But other Lua library functions or modules don't know how to deal with this. So for maximum portability, one needs to use `tonumber()` on returned `long` results before passing them on. Otherwise the application might work on some systems, but would fail in a POSIX/x64 environment.
## Defining Metamethods for a C Type
The following code explains how to define metamethods for a C type. We define a simple point type and add some operations to it:
```lua
local ffi = require "ffi";
ffi.cdef [[
typedef struct { double x, y; } point_t;
]]; -- (1)
local point; -- (2)
local mt = { __index = {} };
function mt.__add(a, b) -- (3)
return point(a.x + b.x, a.y + b.y);
end
function mt.__len(a)
return math.sqrt(a.x * a.x + a.y * a.y);
end
function mt.__index.area(a) -- (4)
return a.x * a.x + a.y * a.y;
end
point = ffi.metatype("point_t", mt); -- (5)
local a = point(3, 4); -- (6)
print(a.x, a.y); --> 3 4
print(#a); --> 5
print(a:area()); --> 25
local b = a + point(0.5, 8);
print(#b); --> 12.5
```
Here's the step-by-step explanation:
1. This defines the C type for a two-dimensional point object.
2. We have to declare the variable holding the point constructor first, because it's used inside of a metamethod.
3. Let's define an `__add` metamethod which adds the coordinates of two points and creates a new point object. For simplicity, this function assumes that both arguments are points. But it could be any mix of objects, if at least one operand is of the required type (e.g. adding a point plus a number or vice versa). Our `__len` metamethod returns the distance of a point to the origin.
4. If we run out of operators, we can define
named methods, too. Here, the `__index` table defines an `area`
function. For custom indexing needs, one might want to define `__index`
and `__newindex` *functions* instead.
5. This associates the metamethods with our C type. This only needs to be done once. For convenience, a constructor is returned by [`ffi.metatype()`](./ext_ffi_api#ffi_metatype). We're not required to use it, though. The original C type can still be used e.g. to create an array of points. The metamethods automatically apply to any and all uses of this type. <br> Please note, that the association with a metatable is permanent and
**the metatable must not be modified afterwards!** Ditto for the `__index` table.
6. Here are some simple usage examples for the point type and their expected results. The predefined operations (such as `a.x`) can be freely mixed with the newly defined metamethods. Note that `area` is a method and must be called with the Lua syntax for methods: `a:area()`, not `a.area()`.
The C type metamethod mechanism is most useful when used in conjunction with C libraries that are written in an object-oriented style. Creators return a pointer to a new instance, and methods take an instance pointer as the first argument. Sometimes you can just point `__index` to the library namespace and `__gc` to the destructor and you're done. But often enough you'll want to add convenience wrappers, e.g. to return actual Lua strings or when returning multiple values.
Some C libraries only declare instance pointers as an opaque `void *` type. In this case you can use a fake type for all declarations, e.g. a pointer to a named (incomplete) struct will do: `typedef struct foo_type *foo_handle`. The C side doesn't know what you declare with the LuaJIT FFI, but as long as the underlying types are compatible, everything still works.
## Translating C Idioms
Here's a list of common C idioms and their translation to the LuaJIT FFI:
Idiom | C code | Lua code
-------------------------------|------------------------------------|------
Pointer dereference | `x = *p; *p = y;` | `x = p[0]; p[0] = y;`
Pointer/array indexing | `x = p[i]; p[i] = y;` | `x = p[i]; p[i] = y;`
`struct`/`union` dereference | `x = s.field; s.field = y;` | `x = s.field; s.field = y;`
`struct`/`union` pointer deref | `x = s->field; s->field = y;` | `x = s.field; s.field = y;`
Pointer arithmetic | `x = p + i; y = p - i;` | `x = p + i; y = p - i;`
Pointer difference | `x = p1 - p2;` | `x = p1 - p2;`
Array element pointer | `x = &a[i];` | `x = a + i;`
Cast pointer to address | `x = (intptr_t)p;` | `x = tonumber(ffi.cast("intptr_t", p));`
Functions with outargs | `int len = x; foo(&len); y = len;` | `local len = ffi.new("int[1]", x); foo(len); y = len[0];`
[Vararg conversions](./ext_ffi_semantics#convert_vararg) | `printf("%g, %d", 1.0, 1);` | `printf("%g, %d", 1, ffi.new("int", 1));`
## To Cache or Not to Cache
It's a common Lua idiom to cache library functions in local variables or upvalues, e.g.:
```lua
local byte, char = string.byte, string.char;
local function foo(x)
return char(byte(x) + 1);
end
```
This replaces several hash-table lookups with a (faster) direct use of a local or an upvalue. This is less important with LuaJIT, since the JIT compiler optimizes hash-table lookups a lot and is even able to hoist most of them out of the inner loops. It can't eliminate *all* of them, though, and it saves some typing for often-used functions. So there's still a place for this, even with LuaJIT.
The situation is a bit different with C function calls via the FFI library. The JIT compiler has special logic to eliminate *all of the lookup overhead* for functions resolved from a [C library namespace](./ext_ffi_semantics#clib)! Thus it's not helpful and actually counter-productive to cache individual C functions like this:
```lua
-- Not helpful!
local funca = ffi.C.funca;
local funcb = ffi.C.funcb;
local function foo(x, n)
for i = 1,n do funcb(funca(x, i), 1) end
end
```
This turns them into indirect calls and generates bigger and slower machine code. Instead, you'll want to cache the namespace itself and rely on the JIT compiler to eliminate the lookups:
```lua
-- Instead use this!
local C = ffi.C;
local function foo(x, n)
for i = 1, n do
C.funcb(C.funca(x, i), 1);
end
end
```
This generates both shorter and faster code. So **don't cache C functions**, but **do** cache namespaces! Most often the namespace is already in a local variable at an outer scope, e.g. from `local lib = ffi.load(...)`. Note that copying it to a local variable in the function scope is unnecessary.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

70
doc/index.md Normal file
View File

@ -0,0 +1,70 @@
# LuaJIT
LuaJIT is a **Just-In-Time Compiler** (JIT) for the
[» Lua](https://www.lua.org/) programming language. Lua is a powerful, dynamic and light-weight programming language. It may be embedded or used as a general-purpose, stand-alone language.
LuaJIT is Copyright © 2005-2025 Mike Pall, released under the [» MIT open source license](https://www.opensource.org/licenses/mit-license.php).
## Compatibility
Supported platforms:
- Windows
- Linux
- BSD
- macOS
- POSIX
- Embedded
- Android
- iOS
- PS3
- PS4
- PS5
- PS Vita
- Xbox 360
- Xbox One
- Nintendo
- Switch
Supported architectures:
- x86
- x64
- ARM
- ARM64
- PPC
- MIPS32
- MIPS64
Supported compilers:
- GCC
- Clang
- LLVM
- MSVC
Compatible with:
- Lua 5.1 API+ABI
- +JIT
- +BitOp
- +FFI
- Drop-in DLL/.so
## Overview
LuaJIT has been successfully used as a **scripting middleware** in games, appliances, network and graphics apps, numerical simulations, trading platforms and many other specialty applications.
LuaJIT is part of a hundred million web sites, huge SaaS installations, network switches, set-top boxes and other embedded devices. You've probably already used LuaJIT without knowing about it.
LuaJIT scales from embedded devices, smartphones, desktops up to server farms. It combines high flexibility with high performance and an unmatched **low memory footprint**.
LuaJIT has been in continuous development since 2005. It's widely considered to be **one of the fastest dynamic language implementations**. It has outperformed other dynamic languages on many cross-language benchmarks since its first release — often by a substantial margin.
For **LuaJIT 2.0**, the whole VM has been rewritten from the ground up and relentlessly optimized for performance. It combines a **high-speed interpreter**, written in assembler, with a **state-of-the-art JIT compiler**.
An innovative **trace compiler** is integrated with advanced, SSA-based optimizations and highly tuned code generation backends. A substantial reduction of the overhead associated with dynamic languages allows it to break into the performance range traditionally reserved for offline, static language compilers.
## More ...
Please select a sub-topic in the navigation bar to learn more about LuaJIT.

View File

@ -1,582 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Installation</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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">
table.compat {
line-height: 1.2;
font-size: 80%;
}
table.compat td {
border: 1px solid #bfcfff;
height: 1.5em;
}
table.compat tr.compathead td {
font-weight: bold;
border-bottom: 2px solid #bfcfff;
}
td.compatname {
width: 10%;
}
td.compatbits {
width: 5%;
}
td.compatx {
width: 21%;
}
</style>
</head>
<body>
<div id="site">
<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1>Installation</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 class="current" 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 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
LuaJIT is only distributed as source code &mdash; get it from the
<a href="https://luajit.org/download.html"><span class="ext">&raquo;</span>&nbsp;git repository</a>. This page explains how to build
and install the LuaJIT binary and library for different operating systems.
</p>
<p>
For the impatient (on POSIX systems):
</p>
<pre class="code">
make &amp;&amp; sudo make install
</pre>
<h2 id="req">Requirements</h2>
<p>
LuaJIT currently builds out-of-the box on most systems. Please check the
supported operating systems and CPU architectures on the
<a href="https://luajit.org/status.html"><span class="ext">&raquo;</span>&nbsp;status page</a>.
</p>
<p>
Building LuaJIT requires a recent toolchain based on GCC, Clang/LLVM or
MSVC++.
</p>
<p>
The Makefile-based build system requires GNU Make and supports
cross-builds.
</p>
<p>
Batch files are provided for MSVC++ builds and console cross-builds.
</p>
<h2>Configuring LuaJIT</h2>
<p>
The standard configuration should work fine for most installations.
Usually there is no need to tweak the settings. The following files
hold all user-configurable settings:
</p>
<ul>
<li><tt>Makefile</tt> has settings for <b>installing</b> LuaJIT (POSIX
only).</li>
<li><tt>src/Makefile</tt> has settings for <b>compiling</b> LuaJIT
under POSIX, MinGW or Cygwin.</li>
<li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with
MSVC (Visual Studio).</li>
</ul>
<p>
Please read the instructions given in these files, before changing
any settings.
</p>
<p>
All LuaJIT 64 bit ports use 64 bit GC objects by default (<tt>LJ_GC64</tt>).
For x64, you can select the old 32-on-64 bit mode by adding
<tt>XCFLAGS=-DLUAJIT_DISABLE_GC64</tt> to the make command.
Please check the note about the
<a href="extensions.html#string_dump">bytecode format</a> differences, too.
</p>
<h2 id="posix">POSIX Systems (Linux, macOS, *BSD etc.)</h2>
<h3>Prerequisites</h3>
<p>
Depending on your distribution, you may need to install a package for a
compiler (GCC or Clang/LLVM), the development headers and/or a complete SDK.
E.g. on a current Debian/Ubuntu, install <tt>build-essential</tt> with the
package manager.
</p>
</pre>
<h3>Building LuaJIT</h3>
<p>
The supplied Makefiles try to auto-detect the settings needed for your
operating system and your compiler. They need to be run with GNU Make,
which is probably the default on your system, anyway. Simply run:
</p>
<pre class="code">
make
</pre>
<p>
This always builds a native binary, depending on the host OS
you're running this command on. Check the section on
<a href="#cross">cross-compilation</a> for more options.
</p>
<p>
By default, modules are only searched under the prefix <tt>/usr/local</tt>.
You can add an extra prefix to the search paths by appending the
<tt>PREFIX</tt> option, e.g.:
</p>
<pre class="code">
make PREFIX=/home/myself/lj2
</pre>
<p>
Note for macOS: you <b>must</b> set the <tt>MACOSX_DEPLOYMENT_TARGET</tt>
environment variable to a value supported by your toolchain:
</p>
<pre class="code">
MACOSX_DEPLOYMENT_TARGET=XX.YY make
</pre>
<h3>Installing LuaJIT</h3>
<p>
The top-level Makefile installs LuaJIT by default under
<tt>/usr/local</tt>, i.e. the executable ends up in
<tt>/usr/local/bin</tt> and so on. You need root privileges
to write to this path. So, assuming sudo is installed on your system,
run the following command and enter your sudo password:
</p>
<pre class="code">
sudo make install
</pre>
<p>
Otherwise specify the directory prefix as an absolute path, e.g.:
</p>
<pre class="code">
make install PREFIX=/home/myself/lj2
</pre>
<p>
Obviously the prefixes given during build and installation need to be the same.
</p>
<h2 id="windows">Windows Systems</h2>
<h3>Prerequisites</h3>
<p>
Either install one of the open source SDKs
(<a href="http://mingw.org/"><span class="ext">&raquo;</span>&nbsp;MinGW</a> or
<a href="https://www.cygwin.com/"><span class="ext">&raquo;</span>&nbsp;Cygwin</a>), which come with a modified
GCC plus the required development headers.
Or install Microsoft's Visual Studio (MSVC).
</p>
<h3>Building with MSVC</h3>
<p>
Open a "Visual Studio Command Prompt" (x86, x64 or ARM64), <tt>cd</tt> to the
directory with the source code and run these commands:
</p>
<pre class="code">
cd src
msvcbuild
</pre>
<p>
Check the <tt>msvcbuild.bat</tt> file for more options.
Then follow the installation instructions below.
</p>
<p>
For an x64 to ARM64 cross-build run this first: <tt>vcvarsall.bat x64_arm64</tt>
</p>
<h3>Building with MinGW or Cygwin</h3>
<p>
Open a command prompt window and make sure the MinGW or Cygwin programs
are in your path. Then <tt>cd</tt> to the directory of the git repository.
Then run this command for MinGW:
</p>
<pre class="code">
mingw32-make
</pre>
<p>
Or this command for Cygwin:
</p>
<pre class="code">
make
</pre>
<p>
Then follow the installation instructions below.
</p>
<h3>Installing LuaJIT</h3>
<p>
Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> (built in the <tt>src</tt>
directory) to a newly created directory (any location is ok).
Add <tt>lua</tt> and <tt>lua\jit</tt> directories below it and copy
all Lua files from the <tt>src\jit</tt> directory of the distribution
to the latter directory.
</p>
<p>
There are no hardcoded
absolute path names &mdash; all modules are loaded relative to the
directory where <tt>luajit.exe</tt> is installed
(see <tt>src/luaconf.h</tt>).
</p>
<h2 id="cross">Cross-compiling LuaJIT</h2>
<p>
First, let's clear up some terminology:
</p>
<ul>
<li>Host: This is your development system, usually based on a x64 or x86 CPU.</li>
<li>Target: This is the target system you want LuaJIT to run on, e.g. Android/ARM.</li>
<li>Toolchain: This comprises a C compiler, linker, assembler and a matching C library.</li>
<li>Host (or system) toolchain: This is the toolchain used to build native binaries for your host system.</li>
<li>Cross-compile toolchain: This is the toolchain used to build binaries for the target system. They can only be run on the target system.</li>
</ul>
<p>
The GNU Makefile-based build system allows cross-compiling on any host
for any supported target:
</p>
<ul>
<li>Yes, you need a toolchain for both your host <em>and</em> your target!</li>
<li>Both host and target architectures must have the same pointer size.</li>
<li>E.g. if you want to cross-compile to a 32 bit target on a 64 bit host, you need to install the multilib development package (e.g. <tt>libc6-dev-i386</tt> on Debian/Ubuntu) and build a 32 bit host part (<tt>HOST_CC="gcc -m32"</tt>).</li>
<li>On some distro versions, multilib conflicts with cross-compilers. The workaround is to install the x86 cross-compiler package <tt>gcc-i686-linux-gnu</tt> and use it to build the host part (<tt>HOST_CC=i686-linux-gnu-gcc</tt>).</li>
<li>64 bit targets always require compilation on a 64 bit host.</li>
</ul>
<p>
You need to specify <tt>TARGET_SYS</tt> whenever the host OS and the
target OS differ, or you'll get assembler or linker errors:
</p>
<ul>
<li>E.g. if you're compiling on a Windows or macOS host for embedded Linux or Android, you need to add <tt>TARGET_SYS=Linux</tt> to the examples below.</li>
<li>For a minimal target OS, you may need to disable the built-in allocator in <tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.</li>
<li>Don't forget to specify the same <tt>TARGET_SYS</tt> for the install step, too.</li>
</ul>
<p>
Here are some examples where host and target have the same CPU:
</p>
<pre class="code">
# Cross-compile to a 32 bit binary on a multilib x64 OS
make CC="gcc -m32"
# Cross-compile on Debian/Ubuntu for Windows (mingw32 package)
make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
</pre>
<p id="cross2">
The <tt>CROSS</tt> prefix allows specifying a standard GNU cross-compile
toolchain (Binutils, GCC and a matching libc). The prefix may vary
depending on the <tt>--target</tt> the toolchain was built for (note the
<tt>CROSS</tt> prefix has a trailing <tt>"-"</tt>). The examples below
use the canonical toolchain triplets for Linux.
</p>
<p>
Since there's often no easy way to detect CPU features at runtime, it's
important to compile with the proper CPU or architecture settings:
</o>
<ul>
<li>The best way to get consistent results is to specify the correct settings when building the toolchain yourself.</li>
<li>For a pre-built, generic toolchain add <tt>-mcpu=...</tt> or <tt>-march=...</tt> and other necessary flags to <tt>TARGET_CFLAGS</tt>.</li>
<li>For ARM it's important to have the correct <tt>-mfloat-abi=...</tt> setting, too. Otherwise LuaJIT may not run at the full performance of your target CPU.</li>
<li>For MIPS it's important to select a supported ABI (o32 on MIPS32, n64 on MIPS64) and consistently compile your project either with hard-float or soft-float compiler settings.</li>
</ul>
<p>
Here are some examples for targets with a different CPU than the host:
</p>
<pre class="code">
# ARM soft-float
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
TARGET_CFLAGS="-mfloat-abi=soft"
# ARM soft-float ABI with VFP (example for Cortex-A9)
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
TARGET_CFLAGS="-mcpu=cortex-a9 -mfloat-abi=softfp"
# ARM hard-float ABI with VFP (armhf, most modern toolchains)
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf-
# ARM64
make CROSS=aarch64-linux-gnu-
# PPC
make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
# MIPS32 big-endian
make HOST_CC="gcc -m32" CROSS=mips-linux-gnu-
# MIPS32 little-endian
make HOST_CC="gcc -m32" CROSS=mipsel-linux-gnu-
# MIPS64 big-endian
make CROSS=mips-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
# MIPS64 little-endian
make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
</pre>
<p>
You can cross-compile for <b id="android">Android</b> using the <a href="https://developer.android.com/ndk/"><span class="ext">&raquo;</span>&nbsp;Android NDK</a>.
Please adapt the environment variables to match the install locations and the
desired target platform. E.g. Android&nbsp;4.1 corresponds to ABI level&nbsp;16.
</p>
<pre class="code">
# Android/ARM64, aarch64, Android 5.0+ (L)
NDKDIR=/opt/android/ndk
NDKBIN=$NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin
NDKCROSS=$NDKBIN/aarch64-linux-android-
NDKCC=$NDKBIN/aarch64-linux-android21-clang
make CROSS=$NDKCROSS \
STATIC_CC=$NDKCC DYNAMIC_CC="$NDKCC -fPIC" \
TARGET_LD=$NDKCC TARGET_AR="$NDKBIN/llvm-ar rcus" \
TARGET_STRIP=$NDKBIN/llvm-strip
# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.1+ (JB)
NDKDIR=/opt/android/ndk
NDKBIN=$NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin
NDKCROSS=$NDKBIN/arm-linux-androideabi-
NDKCC=$NDKBIN/armv7a-linux-androideabi16-clang
make HOST_CC="gcc -m32" CROSS=$NDKCROSS \
STATIC_CC=$NDKCC DYNAMIC_CC="$NDKCC -fPIC" \
TARGET_LD=$NDKCC TARGET_AR="$NDKBIN/llvm-ar rcus" \
TARGET_STRIP=$NDKBIN/llvm-strip
</pre>
<p>
You can cross-compile for <b id="ios">iOS 3.0+</b> (iPhone/iPad) using the <a href="https://developer.apple.com/ios/"><span class="ext">&raquo;</span>&nbsp;iOS SDK</a>:
</p>
<p style="font-size: 8pt;">
Note: <b>the JIT compiler is disabled for iOS</b>, because regular iOS Apps
are not allowed to generate code at runtime. You'll only get the performance
of the LuaJIT interpreter on iOS. This is still faster than plain Lua, but
much slower than the JIT compiler. Please complain to Apple, not me.
Or use Android. :-p
</p>
<pre class="code">
# iOS/ARM64
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
ICC=$(xcrun --sdk iphoneos --find clang)
ISDKF="-arch arm64 -isysroot $ISDKP"
make DEFAULT_CC=clang CROSS="$(dirname $ICC)/" \
TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
</pre>
<h3 id="consoles">Cross-compiling for consoles</h3>
<p>
Building LuaJIT for consoles requires both a supported host compiler
(x86 or x64) and a cross-compiler from the official console SDK.
</p>
<p>
Due to restrictions on consoles, the JIT compiler is disabled and only
the fast interpreter is built. This is still faster than plain Lua,
but much slower than the JIT compiler. The FFI is disabled, too, since
it's not very useful in such an environment.
</p>
<p>
The following commands build a static library <tt>libluajit.a</tt>,
which can be linked against your game, just like the Lua library.
</p>
<p>
To cross-compile for <b id="ps3">PS3</b> from a Linux host (requires
32&nbsp;bit GCC, i.e. multilib Linux/x64) or a Windows host (requires
32&nbsp;bit MinGW), run this command:
</p>
<pre class="code">
make HOST_CC="gcc -m32" CROSS=ppu-lv2-
</pre>
<p>
To cross-compile for the other consoles from a Windows host, open a
"Native Tools Command Prompt for VS". You need to choose either the 32
or the 64&nbsp;bit version of the host compiler to match the target.
Then <tt>cd</tt> to the <tt>src</tt> directory below the source code
and run the build command given in the table:
</p>
<table class="compat">
<tr class="compathead">
<td class="compatname">Console</td>
<td class="compatbits">Bits</td>
<td class="compatx">Build Command</td>
</tr>
<tr class="odd separate">
<td class="compatname"><b id="ps4">PS4</b></td>
<td class="compatbits">64</td>
<td class="compatx"><tt>ps4build</tt></td>
</tr>
<tr class="even">
<td class="compatname"><b id="ps5">PS5</b></td>
<td class="compatbits">64</td>
<td class="compatx"><tt>ps5build</tt></td>
</tr>
<tr class="odd">
<td class="compatname"><b id="psvita">PS Vita</b></td>
<td class="compatbits">32</td>
<td class="compatx"><tt>psvitabuild</tt></td>
</tr>
<tr class="even">
<td class="compatname"><b id="xbox360">Xbox 360</b></td>
<td class="compatbits">32</td>
<td class="compatx"><tt>xedkbuild</tt></td>
</tr>
<tr class="odd">
<td class="compatname"><b id="xboxone">Xbox One</b></td>
<td class="compatbits">64</td>
<td class="compatx"><tt>xb1build</tt></td>
</tr>
<tr class="even">
<td class="compatname"><b id="nx32">Nintendo Switch NX32</b></td>
<td class="compatbits">32</td>
<td class="compatx"><tt>nxbuild</tt></td>
</tr>
<tr class="odd">
<td class="compatname"><b id="nx64">Nintendo Switch NX64</b></td>
<td class="compatbits">64</td>
<td class="compatx"><tt>nxbuild</tt></td>
</tr>
</table>
<p>
Please check out the comments in the corresponding <tt>*.bat</tt>
file for more options.
</p>
<h2 id="embed">Embedding LuaJIT</h2>
<p>
LuaJIT is API-compatible with Lua 5.1. If you've already embedded Lua
into your application, you probably don't need to do anything to switch
to LuaJIT, except link with a different library:
</p>
<ul>
<li>It's strongly suggested to build LuaJIT separately using the supplied
build system. Please do <em>not</em> attempt to integrate the individual
source files into your build tree. You'll most likely get the internal build
dependencies wrong or mess up the compiler flags. Treat LuaJIT like any
other external library and link your application with either the dynamic
or static library, depending on your needs.</li>
<li>If you want to load C modules compiled for plain Lua
with <tt>require()</tt>, you need to make sure the public symbols
(e.g. <tt>lua_pushnumber</tt>) are exported, too:
<ul><li>On POSIX systems you can either link to the shared library
or link the static library into your application. In the latter case
you'll need to export all public symbols from your main executable
(e.g. <tt>-Wl,-E</tt> on Linux) and add the external dependencies
(e.g. <tt>-lm -ldl</tt> on Linux).</li>
<li>Since Windows symbols are bound to a specific DLL name, you need to
link to the <tt>lua51.dll</tt> created by the LuaJIT build (do not rename
the DLL). You may link LuaJIT statically on Windows only if you don't
intend to load Lua/C modules at runtime.
</li></ul>
</li>
</ul>
<p>Additional hints for initializing LuaJIT using the C API functions:</p>
<ul>
<li>Here's a
<a href="http://lua-users.org/wiki/SimpleLuaApiExample"><span class="ext">&raquo;</span>&nbsp;simple example</a>
for embedding Lua or LuaJIT into your application.</li>
<li>Make sure you use <tt>luaL_newstate</tt>. Avoid using
<tt>lua_newstate</tt>, since this uses the (slower) default memory
allocator from your system (no support for this on 64&nbsp;bit architectures).</li>
<li>Make sure you use <tt>luaL_openlibs</tt> and not the old Lua 5.0 style
of calling <tt>luaopen_base</tt> etc. directly.</li>
<li>To change or extend the list of standard libraries to load, copy
<tt>src/lib_init.c</tt> to your project and modify it accordingly.
Make sure the <tt>jit</tt> library is loaded, or the JIT compiler
will not be activated.</li>
<li>The <tt>bit.*</tt> module for bitwise operations
is already built-in. There's no need to statically link
<a href="https://bitop.luajit.org/"><span class="ext">&raquo;</span>&nbsp;Lua BitOp</a> to your application.</li>
</ul>
<h2 id="distro">Hints for Distribution Maintainers</h2>
<p>
The LuaJIT build system has extra provisions for the needs of most
POSIX-based distributions. If you're a package maintainer for
a distribution, <em>please</em> make use of these features and
avoid patching, subverting, autotoolizing or messing up the build system
in unspeakable ways.
</p>
<p>
There should be absolutely no need to patch <tt>luaconf.h</tt> or any
of the Makefiles. And please do not hand-pick files for your packages &mdash;
simply use whatever <tt>make install</tt> creates. There's a reason
for all the files <em>and</em> directories it creates.
</p>
<p>
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
for a regular distribution build:
</p>
<ul>
<li><tt>PREFIX</tt> overrides the installation path and should usually
be set to <tt>/usr</tt>. Setting this also changes the module paths and
the paths needed to locate the shared library.</li>
<li><tt>DESTDIR</tt> is an absolute path which allows you to install
to a shadow tree instead of the root tree of the build system.</li>
<li><tt>MULTILIB</tt> sets the architecture-specific library path component
for multilib systems. The default is <tt>lib</tt>.</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
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,
TARGET_FLAGS, LIBS, HOST_LIBS, TARGET_LIBS, CROSS, HOST_SYS, TARGET_SYS
</tt></li>
</ul>
<p>
The build system has a special target for an amalgamated build, i.e.
<tt>make amalg</tt>. This compiles the LuaJIT core as one huge C file
and allows GCC to generate faster and shorter code. Alas, this requires
lots of memory during the build. This may be a problem for some users,
that's why it's not enabled by default. But it shouldn't be a problem for
most build farms. It's recommended that binary distributions use this
target for their LuaJIT builds.
</p>
<p>
The tl;dr version of the above:
</p>
<pre class="code">
make amalg PREFIX=/usr && \
make install PREFIX=/usr DESTDIR=/tmp/buildroot
</pre>
<p>
Finally, if you encounter any difficulties, please
<a href="contact.html">contact me</a> first, instead of releasing a broken
package onto unsuspecting users. Because they'll usually gonna complain
to me (the upstream) and not you (the package maintainer), anyway.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

303
doc/install.md Normal file
View File

@ -0,0 +1,303 @@
# Installation
LuaJIT is only distributed as source code — get it from the [» git repository](https://luajit.org/download.html). This page explains how to build and install the LuaJIT binary and library for different operating systems.
For the impatient (on POSIX systems):
```sh
make && sudo make install
```
## Requirements
LuaJIT currently builds out-of-the box on most systems. Please check the supported operating systems and CPU architectures on the [» status page](https://luajit.org/status.html).
Building LuaJIT requires a recent toolchain based on GCC, Clang/LLVM or MSVC++.
The Makefile-based build system requires GNU Make and supports cross-builds.
Batch files are provided for MSVC++ builds and console cross-builds.
## Configuring LuaJIT
The standard configuration should work fine for most installations. Usually there is no need to tweak the settings. The following files hold all user-configurable settings:
- `Makefile` has settings for **installing** LuaJIT (POSIX only).
- `src/Makefile` has settings for **compiling** LuaJIT under POSIX, MinGW or Cygwin.
- `src/msvcbuild.bat` has settings for compiling LuaJIT with MSVC (Visual Studio).
Please read the instructions given in these files, before changing any settings.
All LuaJIT 64 bit ports use 64 bit GC objects by default (`LJ_GC64`). For x64, you can select the old 32-on-64 bit mode by adding `XCFLAGS=-DLUAJIT_DISABLE_GC64` to the make command. Please check the note about the [bytecode format](./extensions#stringdumpf-mode-generates-portable-bytecode) differences, too.
## POSIX Systems (Linux, macOS, *BSD etc.)
### Prerequisites
Depending on your distribution, you may need to install a package for a compiler (GCC or Clang/LLVM), the development headers and/or a complete SDK. E.g. on a current Debian/Ubuntu, install `build-essential` with the package manager.
### Building LuaJIT
The supplied Makefiles try to auto-detect the settings needed for your operating system and your compiler. They need to be run with GNU Make, which is probably the default on your system, anyway. Simply run:
```sh
make
```
This always builds a native binary, depending on the host OS you're running this command on. Check the section on [cross-compilation](#cross-compiling-luajit) for more options.
By default, modules are only searched under the prefix `/usr/local`. You can add an extra prefix to the search paths by appending the `PREFIX` option, e.g.:
```sh
make PREFIX=/home/myself/lj2
```
Note for macOS: you **must** set the `MACOSX_DEPLOYMENT_TARGET` environment variable to a value supported by your toolchain:
```sh
MACOSX_DEPLOYMENT_TARGET=XX.YY make
```
### Installing LuaJIT
The top-level Makefile installs LuaJIT by default under `/usr/local`, i.e. the executable ends up in `/usr/local/bin` and so on. You need root privileges to write to this path. So, assuming sudo is installed on your system, run the following command and enter your sudo password:
```sh
sudo make install
```
Otherwise specify the directory prefix as an absolute path, e.g.:
```sh
make install PREFIX=/home/myself/lj2
```
Obviously the prefixes given during build and installation need to be the same.
## Windows Systems
### Prerequisites
Either install one of the open source SDKs ([» MinGW](http://mingw.org/) or [» Cygwin](https://www.cygwin.com/)), which come with a modified GCC plus the required development headers. Or install Microsoft's Visual Studio (MSVC).
### Building with MSVC
Open a "Visual Studio Command Prompt" (x86, x64 or ARM64), `cd` to the directory with the source code and run these commands:
```sh
cd src
msvcbuild
```
Check the `msvcbuild.bat` file for more options. Then follow the installation instructions below.
For an x64 to ARM64 cross-build run this first: `vcvarsall.bat x64_arm64`
### Building with MinGW or Cygwin
Open a command prompt window and make sure the MinGW or Cygwin programs are in your path. Then `cd` to the directory of the git repository. Then run this command for MinGW:
```sh
mingw32-make
```
Or this command for Cygwin:
```sh
make
```
Then follow the installation instructions below.
### Installing LuaJIT
Copy `luajit.exe` and `lua51.dll` (built in the `src` directory) to a newly created directory (any location is ok). Add `lua` and `lua\jit` directories below it and copy all Lua files from the `src\jit` directory of the distribution to the latter directory.
There are no hardcoded absolute path names — all modules are loaded relative to the directory where `luajit.exe` is installed (see `src/luaconf.h`).
## Cross-compiling LuaJIT
First, let's clear up some terminology:
- Host: This is your development system, usually based on a x64 or x86 CPU.
- Target: This is the target system you want LuaJIT to run on, e.g. Android/ARM.
- Toolchain: This comprises a C compiler, linker, assembler and a matching C library.
- Host (or system) toolchain: This is the toolchain used to build native binaries for your host system.
- Cross-compile toolchain: This is the toolchain used to build binaries for the target system. They can only be run on the target system.
The GNU Makefile-based build system allows cross-compiling on any host for any supported target:
- Yes, you need a toolchain for both your host *and* your target!
- Both host and target architectures must have the same pointer size.
- E.g. if you want to cross-compile to a 32 bit target on a 64 bit host, you need to install the multilib development package (e.g. `libc6-dev-i386` on Debian/Ubuntu) and build a 32 bit host part (`HOST_CC="gcc -m32"`).
- On some distro versions, multilib conflicts with cross-compilers. The workaround is to install the x86 cross-compiler package `gcc-i686-linux-gnu` and use it to build the host part (`HOST_CC=i686-linux-gnu-gcc`).
- 64 bit targets always require compilation on a 64 bit host.
You need to specify `TARGET_SYS` whenever the host OS and the target OS
differ, or you'll get assembler or linker errors:
- E.g. if you're compiling on a Windows or macOS host for embedded Linux or Android, you need to add `TARGET_SYS=Linux` to the examples below.
- For a minimal target OS, you may need to disable the built-in allocator in `src/Makefile` and use `TARGET_SYS=Other`.
- Don't forget to specify the same `TARGET_SYS` for the install step, too.
Here are some examples where host and target have the same CPU:
```sh
# Cross-compile to a 32 bit binary on a multilib x64 OS
make CC="gcc -m32"
# Cross-compile on Debian/Ubuntu for Windows (mingw32 package)
make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
```
The `CROSS` prefix allows specifying a standard GNU cross-compile toolchain (Binutils, GCC and a matching libc). The prefix may vary depending on the `--target` the toolchain was built for (note the `CROSS` prefix has a trailing `"-"`). The examples below use the canonical toolchain triplets for Linux.
Since there's often no easy way to detect CPU features at runtime, it's important to compile with the proper CPU or architecture settings:
- The best way to get consistent results is to specify the correct settings when building the toolchain yourself.
- For a pre-built, generic toolchain add `-mcpu=...` or `-march=...` and other necessary flags to `TARGET_CFLAGS`.
- For ARM it's important to have the correct `-mfloat-abi=...` setting, too. Otherwise LuaJIT may not run at the full performance of your target CPU.
- For MIPS it's important to select a supported ABI (o32 on MIPS32, n64 on MIPS64) and consistently compile your project either with hard-float or soft-float compiler settings.
Here are some examples for targets with a different CPU than the host:
```sh
# ARM soft-float
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- TARGET_CFLAGS="-mfloat-abi=soft"
# ARM soft-float ABI with VFP (example for Cortex-A9)
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- TARGET_CFLAGS="-mcpu=cortex-a9 -mfloat-abi=softfp"
# ARM hard-float ABI with VFP (armhf, most modern toolchains)
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf-
# ARM64
make CROSS=aarch64-linux-gnu-
# PPC
make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
# MIPS32 big-endian
make HOST_CC="gcc -m32" CROSS=mips-linux-gnu-
# MIPS32 little-endian
make HOST_CC="gcc -m32" CROSS=mipsel-linux-gnu-
# MIPS64 big-endian
make CROSS=mips-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
# MIPS64 little-endian
make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
```
You can cross-compile for **Android** using the
[» Android NDK](https://developer.android.com/ndk/). Please adapt the environment variables to match the install locations and the desired target platform. E.g. Android 4.1 corresponds to ABI level 16.
```sh
# Android/ARM64, aarch64, Android 5.0+ (L)
NDKDIR=/opt/android/ndk
NDKBIN=$NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin
NDKCROSS=$NDKBIN/aarch64-linux-android-
NDKCC=$NDKBIN/aarch64-linux-android21-clang
make \
CROSS=$NDKCROSS \
STATIC_CC=$NDKCC \
DYNAMIC_CC="$NDKCC -fPIC" \
TARGET_LD=$NDKCC \
TARGET_AR="$NDKBIN/llvm-ar rcus" \
TARGET_STRIP=$NDKBIN/llvm-strip
# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.1+ (JB)
NDKDIR=/opt/android/ndk
NDKBIN=$NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin
NDKCROSS=$NDKBIN/arm-linux-androideabi-
NDKCC=$NDKBIN/armv7a-linux-androideabi16-clang
make \
HOST_CC="gcc -m32" \
CROSS=$NDKCROSS \
STATIC_CC=$NDKCC \
DYNAMIC_CC="$NDKCC -fPIC" \
TARGET_LD=$NDKCC \
TARGET_AR="$NDKBIN/llvm-ar rcus" \
TARGET_STRIP=$NDKBIN/llvm-strip
```
You can cross-compile for **iOS 3.0+** (iPhone/iPad) using the [» iOS SDK](https://developer.apple.com/ios/):
Note: **the JIT compiler is disabled for iOS**, because regular iOS Apps are not allowed to generate code at runtime. You'll only get the performance of the LuaJIT interpreter on iOS. This is still faster than plain Lua, but much slower than the JIT compiler. Please complain to Apple, not me. Or use Android. :-p
```sh
# iOS/ARM64
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
ICC=$(xcrun --sdk iphoneos --find clang)
ISDKF="-arch arm64 -isysroot $ISDKP"
make DEFAULT_CC=clang CROSS="$(dirname $ICC)/" TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
```
### Cross-compiling for consoles
Building LuaJIT for consoles requires both a supported host compiler (x86 or x64) and a cross-compiler from the official console SDK.
Due to restrictions on consoles, the JIT compiler is disabled and only the fast interpreter is built. This is still faster than plain Lua, but much slower than the JIT compiler. The FFI is disabled, too, since it's not very useful in such an environment.
The following commands build a static library `libluajit.a`, which can be linked against your game, just like the Lua library.
To cross-compile for **PS3** from a Linux host (requires 32 bit GCC, i.e. multilib Linux/x64) or a Windows host (requires 32 bit MinGW), run this command:
```sh
make HOST_CC="gcc -m32" CROSS=ppu-lv2-
```
To cross-compile for the other consoles from a Windows host, open a "Native Tools Command Prompt for VS". You need to choose either the 32 or the 64 bit version of the host compiler to match the target. Then `cd` to the `src` directory below the source code and run the build command given in the table:
Console | Bits | Build Command
-------------------------|------|---------------
**PS4** | 64 | `ps4build`
**PS5** | 64 | `ps5build`
**PS Vita** | 32 | `psvitabuild`
**Xbox 360** | 32 | `xedkbuild`
**Xbox One** | 64 | `xb1build`
**Nintendo Switch NX32** | 32 | `nxbuild`
**Nintendo Switch NX64** | 64 | `nxbuild`
Please check out the comments in the corresponding `*.bat` file for more options.
## Embedding LuaJIT
LuaJIT is API-compatible with Lua 5.1. If you've already embedded Lua into your application, you probably don't need to do anything to switch to LuaJIT, except link with a different library:
- It's strongly suggested to build LuaJIT separately using the supplied build system. Please do *not* attempt to integrate the individual source files into your build tree. You'll most likely get the internal build dependencies wrong or mess up the compiler flags. Treat LuaJIT like any other external library and link your application with either the dynamic or static library, depending on your needs.
- If you want to load C modules compiled for plain Lua with `require()`, you need to make sure the public symbols (e.g. `lua_pushnumber`) are exported, too:
- On POSIX systems you can either link to the shared library or link the static library into your application. In the latter case you'll need to export all public symbols from your main executable (e.g. `-Wl,-E` on Linux) and add the external dependencies (e.g. `-lm -ldl` on Linux).
- Since Windows symbols are bound to a specific DLL name, you need to link to the `lua51.dll` created by the LuaJIT build (do not rename the DLL). You may link LuaJIT statically on Windows only if you don't intend to load Lua/C modules at runtime.
Additional hints for initializing LuaJIT using the C API functions:
- Here's a [» simple example](http://lua-users.org/wiki/SimpleLuaApiExample) for embedding Lua or LuaJIT into your application.
- Make sure you use `luaL_newstate`. Avoid using `lua_newstate`, since this uses the (slower) default memory allocator from your system (no support for this on 64 bit architectures).
- Make sure you use `luaL_openlibs` and not the old Lua 5.0 style of calling `luaopen_base` etc. directly.
- To change or extend the list of standard libraries to load, copy `src/lib_init.c` to your project and modify it accordingly. Make sure the `jit` library is loaded, or the JIT compiler will not be activated.
- The `bit.*` module for bitwise operations is already built-in. There's no need to statically link [» Lua BitOp](https://bitop.luajit.org/) to your application.
## Hints for Distribution Maintainers
The LuaJIT build system has extra provisions for the needs of most POSIX-based distributions. If you're a package maintainer for a distribution, *please* make use of these features and avoid patching, subverting, autotoolizing or messing up the build system in unspeakable ways.
There should be absolutely no need to patch `luaconf.h` or any of the Makefiles. And please do not hand-pick files for your packages — simply use whatever `make install` creates. There's a reason for all the files *and* directories it creates.
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 *both* the `make` and the `make install` command lines for a regular distribution build:
- `PREFIX` overrides the installation path and should usually be set to `/usr`. Setting this also changes the module paths and the paths needed to locate the shared library.
- `DESTDIR` is an absolute path which allows you to install to a shadow tree instead of the root tree of the build system.
- `MULTILIB` sets the architecture-specific library path component for multilib systems. The default is `lib`.
- Have a look at the top-level `Makefile` and `src/Makefile` for additional variables to tweak. The following variables *may* be overridden, but it's *not* recommended, except for special needs like cross-builds: `BUILDMODE, CC, HOST_CC, STATIC_CC, DYNAMIC_CC, CFLAGS, HOST_CFLAGS, TARGET_CFLAGS, LDFLAGS, HOST_LDFLAGS, TARGET_LDFLAGS, TARGET_SHLDFLAGS, TARGET_FLAGS, LIBS, HOST_LIBS, TARGET_LIBS, CROSS, HOST_SYS, TARGET_SYS `
The build system has a special target for an amalgamated build, i.e. `make amalg`. This compiles the LuaJIT core as one huge C file and allows GCC to generate faster and shorter code. Alas, this requires lots of memory during the build. This may be a problem for some users, that's why it's not enabled by default. But it shouldn't be a problem for most build farms. It's recommended that binary distributions use this target for their LuaJIT builds.
The tl;dr version of the above:
```sh
make amalg PREFIX=/usr && \
make install PREFIX=/usr DESTDIR=/tmp/buildroot
```
Finally, if you encounter any difficulties, please [contact me](./contact) first, instead of releasing a broken package onto unsuspecting users. Because they'll usually gonna complain to me (the upstream) and not you (the package maintainer), anyway.

View File

@ -1,203 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>LuaJIT</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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">
<meta name="description" content="LuaJIT is a Just-In-Time (JIT) compiler for the Lua language.">
<style type="text/css">
table.feature {
width: inherit;
line-height: 1.2;
margin: 0;
}
table.feature td {
width: 80px;
height: 40px;
vertical-align: middle;
text-align: center;
font-weight: bold;
border: 4px solid #e6ecff;
border-radius: 12px;
}
table.os td {
background: #7080d0;
background-image: linear-gradient(#4060c0 10%, #b0b0ff 95%);
background-image: -moz-linear-gradient(#4060c0 10%, #b0b0ff 95%);
background-image: -webkit-linear-gradient(#4060c0 10%, #b0b0ff 95%);
background-image: -o-linear-gradient(#4060c0 10%, #b0b0ff 95%);
background-image: -ms-linear-gradient(#4060c0 10%, #b0b0ff 95%);
}
table.os1 td {
color: #ffff80;
}
table.os2 td {
color: #ffa040;
}
table.os3 td {
color: #40ffff;
}
table.compiler td {
color: #2080ff;
background: #62bf41;
background-image: linear-gradient(#62bf41 10%, #b0ffb0 95%);
background-image: -moz-linear-gradient(#62bf41 10%, #b0ffb0 95%);
background-image: -webkit-linear-gradient(#62bf41 10%, #b0ffb0 95%);
background-image: -o-linear-gradient(#62bf41 10%, #b0ffb0 95%);
background-image: -ms-linear-gradient(#62bf41 10%, #b0ffb0 95%);
}
table.cpu td {
color: #ffff00;
background: #cf7251;
background-image: linear-gradient(#bf6241 10%, #ffb0b0 95%);
background-image: -moz-linear-gradient(#bf6241 10%, #ffb0b0 95%);
background-image: -webkit-linear-gradient(#bf6241 10%, #ffb0b0 95%);
background-image: -o-linear-gradient(#bf6241 10%, #ffb0b0 95%);
background-image: -ms-linear-gradient(#bf6241 10%, #ffb0b0 95%);
}
table.fcompat td {
color: #2060e0;
background: #61cfcf;
background-image: linear-gradient(#41bfbf 10%, #b0ffff 95%);
background-image: -moz-linear-gradient(#41bfbf 10%, #b0ffff 95%);
background-image: -webkit-linear-gradient(#41bfbf 10%, #b0ffff 95%);
background-image: -o-linear-gradient(#41bfbf 10%, #b0ffff 95%);
background-image: -ms-linear-gradient(#41bfbf 10%, #b0ffff 95%);
}
</style>
</head>
<body>
<div id="site">
<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1>LuaJIT</h1>
</div>
<div id="nav">
<ul><li>
<a class="current" 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 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
LuaJIT is a <b>Just-In-Time Compiler</b> (JIT) for the
<a href="https://www.lua.org/"><span class="ext">&raquo;</span>&nbsp;Lua</a> programming language.
Lua is a powerful, dynamic and light-weight programming language.
It may be embedded or used as a general-purpose, stand-alone language.
</p>
<p>
LuaJIT is Copyright &copy; 2005-2025 Mike Pall, released under the
<a href="https://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT open source license</a>.
</p>
<p>
</p>
<h2>Compatibility</h2>
<table class="feature os os1">
<tr><td>Windows</td><td>Linux</td><td>BSD</td><td>macOS</td><td>POSIX</td></tr>
</table>
<table class="feature os os2">
<tr><td><span style="font-size:90%;">Embedded</span></td><td>Android</td><td>iOS</td></tr>
</table>
<table class="feature os os3">
<tr><td>PS3</td><td>PS4<br>PS5</td><td>PS Vita</td><td>Xbox 360</td><td>Xbox One</td><td>Nintendo<br>Switch</td></tr>
</table>
<table class="feature compiler">
<tr><td>GCC</td><td>Clang<br>LLVM</td><td>MSVC</td></tr>
</table>
<table class="feature cpu">
<tr><td>x86<br>x64</td><td>ARM<br>ARM64</td><td>PPC</td><td>MIPS32<br>MIPS64</td></tr>
</table>
<table class="feature fcompat">
<tr><td>Lua&nbsp;5.1<br>API+ABI</td><td>+&nbsp;JIT</td><td>+&nbsp;BitOp</td><td>+&nbsp;FFI</td><td>Drop-in<br>DLL/.so</td></tr>
</table>
<h2>Overview</h2>
<p style="margin-top: 1em;">
LuaJIT has been successfully used as a <b>scripting middleware</b> in
games, appliances, network and graphics apps, numerical simulations,
trading platforms and many other specialty applications.
</p>
<p>
LuaJIT is part of a hundred million web sites, huge SaaS installations,
network switches, set-top boxes and other embedded devices. You've probably
already used LuaJIT without knowing about it.
</p>
<p>
LuaJIT scales from embedded devices, smartphones, desktops up to server
farms. It combines high flexibility with high performance and an unmatched
<b>low memory footprint</b>.
</p>
<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 outperformed other dynamic languages on many
cross-language benchmarks since its first release &mdash; often by a
substantial margin.
</p>
<p>
For <b>LuaJIT 2.0</b>, the whole VM has been rewritten from the ground up
and relentlessly optimized for performance. It combines a <b>high-speed
interpreter</b>, written in assembler, with a <b>state-of-the-art JIT
compiler</b>.
</p>
<p>
An innovative <b>trace compiler</b> is integrated with advanced,
SSA-based optimizations and highly tuned code generation backends.
A substantial reduction of the overhead associated with dynamic languages
allows it to break into the performance range traditionally reserved for
offline, static language compilers.
</p>
<h2>More ...</h2>
<p>
Please select a sub-topic in the navigation bar to learn more about LuaJIT.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

View File

@ -1,317 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Running LuaJIT</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2025">
<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">
table.opt {
line-height: 1.2;
}
tr.opthead td {
font-weight: bold;
}
td.flag_name {
width: 4em;
}
td.flag_level {
width: 2em;
text-align: center;
}
td.param_name {
width: 6em;
}
td.param_default {
width: 4em;
text-align: right;
}
</style>
</head>
<body>
<div id="site">
<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1>Running LuaJIT</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 class="current" href="running.html">Running</a>
</li></ul>
</li><li>
<a href="extensions.html">Extensions</a>
<ul><li>
<a 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="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
</li><li>
<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></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>
LuaJIT has only a single stand-alone executable, called <tt>luajit</tt> on
POSIX systems or <tt>luajit.exe</tt> on Windows. It can be used to run simple
Lua statements or whole Lua applications from the command line. It has an
interactive mode, too.
</p>
<h2 id="options">Command Line Options</h2>
<p>
The <tt>luajit</tt> stand-alone executable is just a slightly modified
version of the regular <tt>lua</tt> stand-alone executable.
It supports the same basic options, too. <tt>luajit&nbsp;-h</tt>
prints a short list of the available options. Please have a look at the
<a href="https://www.lua.org/manual/5.1/manual.html#6"><span class="ext">&raquo;</span>&nbsp;Lua manual</a>
for details.
</p>
<p>
LuaJIT has some additional options:
</p>
<h3 id="opt_b"><tt>-b[options] input output</tt></h3>
<p>
This option saves or lists bytecode. The following additional options
are accepted:
</p>
<ul>
<li><tt>-l</tt> &mdash; Only list bytecode.</li>
<li><tt>-s</tt> &mdash; Strip debug info (this is the default).</li>
<li><tt>-g</tt> &mdash; Keep debug info.</li>
<li><tt>-W</tt> &mdash; Generate 32 bit (non-GC64) bytecode.</li>
<li><tt>-X</tt> &mdash; Generate 64 bit (GC64) bytecode.</li>
<li><tt>-d</tt> &mdash; Generate bytecode in deterministic manner.</li>
<li><tt>-n name</tt> &mdash; Set module name (default: auto-detect from input name)</li>
<li><tt>-t type</tt> &mdash; Set output file type (default: auto-detect from output name).</li>
<li><tt>-a arch</tt> &mdash; Override architecture for object files (default: native).</li>
<li><tt>-o os</tt> &mdash; Override OS for object files (default: native).</li>
<li><tt>-F name</tt> &mdash; Override filename (default: input filename).</li>
<li><tt>-e chunk</tt> &mdash; Use chunk string as input.</li>
<li><tt>-</tt> (a single minus sign) &mdash; Use stdin as input and/or stdout as output.</li>
</ul>
<p>
The output file type is auto-detected from the extension of the output
file name:
</p>
<ul>
<li><tt>c</tt> &mdash; C source file, exported bytecode data.</li>
<li><tt>cc</tt> &mdash; C++ source file, exported bytecode data.</li>
<li><tt>h</tt> &mdash; C/C++ header file, static bytecode data.</li>
<li><tt>obj</tt> or <tt>o</tt> &mdash; Object file, exported bytecode data
(OS- and architecture-specific).</li>
<li><tt>raw</tt> or any other extension &mdash; Raw bytecode file (portable).
</ul>
<p>
Notes:
</p>
<ul>
<li>See also <a href="extensions.html#string_dump">string.dump()</a>
for information on bytecode portability and compatibility.</li>
<li>A file in raw bytecode format is auto-detected and can be loaded like
any Lua source file. E.g. directly from the command line or with
<tt>loadfile()</tt>, <tt>dofile()</tt> etc.</li>
<li>To statically embed the bytecode of a module in your application,
generate an object file and just link it with your application.</li>
<li>On most ELF-based systems (e.g. Linux) you need to explicitly export the
global symbols when linking your application, e.g. with: <tt>-Wl,-E</tt></li>
<li><tt>require()</tt> tries to load embedded bytecode data from exported
symbols (in <tt>*.exe</tt> or <tt>lua51.dll</tt> on Windows) and from
shared libraries in <tt>package.cpath</tt>.</li>
</ul>
<p>
Typical usage examples:
</p>
<pre class="code">
luajit -b test.lua test.out # Save bytecode to test.out
luajit -bg test.lua test.out # Keep debug info
luajit -be "print('hello world')" test.out # Save cmdline script
luajit -bl test.lua # List to stdout
luajit -bl test.lua test.txt # List to test.txt
luajit -ble "print('hello world')" # List cmdline script
luajit -b test.lua test.obj # Generate object file
# Link test.obj with your application and load it with require("test")
</pre>
<h3 id="opt_j"><tt>-j cmd[=arg[,arg...]]</tt></h3>
<p>
This option performs a LuaJIT control command or activates one of the
loadable extension modules. The command is first looked up in the
<tt>jit.*</tt> library. If no matching function is found, a module
named <tt>jit.&lt;cmd&gt;</tt> is loaded and the <tt>start()</tt>
function of the module is called with the specified arguments (if
any). The space between <tt>-j</tt> and <tt>cmd</tt> is optional.
</p>
<p>
Here are the available LuaJIT control commands:
</p>
<ul>
<li id="j_on"><tt>-jon</tt> &mdash; Turns the JIT compiler on (default).</li>
<li id="j_off"><tt>-joff</tt> &mdash; Turns the JIT compiler off (only use the interpreter).</li>
<li id="j_flush"><tt>-jflush</tt> &mdash; Flushes the whole cache of compiled code.</li>
<li id="j_v"><tt>-jv</tt> &mdash; Shows verbose information about the progress of the JIT compiler.</li>
<li id="j_dump"><tt>-jdump</tt> &mdash; Dumps the code and structures used in various compiler stages.</li>
<li id="j_p"><tt>-jp</tt> &mdash; Start the <a href="ext_profiler.html">integrated profiler</a>.</li>
</ul>
<p>
The <tt>-jv</tt> and <tt>-jdump</tt> commands are extension modules
written in Lua. They are mainly used for debugging the JIT compiler
itself. For a description of their options and output format, please
read the comment block at the start of their source.
They can be found in the <tt>lib</tt> directory of the source
distribution or installed under the <tt>jit</tt> directory. By default,
this is <tt>/usr/local/share/luajit-XX.YY.ZZ>/jit</tt> on POSIX
systems (replace XX.YY.ZZ by the installed version).
</p>
<h3 id="opt_O"><tt>-O[level]</tt><br>
<tt>-O[+]flag</tt>&nbsp;&nbsp;&nbsp;<tt>-O-flag</tt><br>
<tt>-Oparam=value</tt></h3>
<p>
This options allows fine-tuned control of the optimizations used by
the JIT compiler. This is mainly intended for debugging LuaJIT itself.
Please note that the JIT compiler is extremely fast (we are talking
about the microsecond to millisecond range). Disabling optimizations
doesn't have any visible impact on its overhead, but usually generates
code that runs slower.
</p>
<p>
The first form sets an optimization level &mdash; this enables a
specific mix of optimization flags. <tt>-O0</tt> turns off all
optimizations and higher numbers enable more optimizations. Omitting
the level (i.e. just <tt>-O</tt>) sets the default optimization level,
which is <tt>-O3</tt> in the current version.
</p>
<p>
The second form adds or removes individual optimization flags.
The third form sets a parameter for the VM or the JIT compiler
to a specific value.
</p>
<p>
You can either use this option multiple times (like <tt>-Ocse
-O-dce -Ohotloop=10</tt>) or separate several settings with a comma
(like <tt>-O+cse,-dce,hotloop=10</tt>). The settings are applied from
left to right, and later settings override earlier ones. You can freely
mix the three forms, but note that setting an optimization level
overrides all earlier flags.
</p>
<p>
Note that <tt>-Ofma</tt> is not enabled by default at any level,
because it affects floating-point result accuracy. Only enable this,
if you fully understand the trade-offs of FMA for performance (higher),
determinism (lower) and numerical accuracy (higher).
</p>
<p>
Here are the available flags and at what optimization levels they
are enabled:
</p>
<table class="opt">
<tr class="opthead">
<td class="flag_name">Flag</td>
<td class="flag_level">-O1</td>
<td class="flag_level">-O2</td>
<td class="flag_level">-O3</td>
<td class="flag_desc">&nbsp;</td>
</tr>
<tr class="odd separate">
<td class="flag_name">fold</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Constant Folding, Simplifications and Reassociation</td></tr>
<tr class="even">
<td class="flag_name">cse</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Common-Subexpression Elimination</td></tr>
<tr class="odd">
<td class="flag_name">dce</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Dead-Code Elimination</td></tr>
<tr class="even">
<td class="flag_name">narrow</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Narrowing of numbers to integers</td></tr>
<tr class="odd">
<td class="flag_name">loop</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Loop Optimizations (code hoisting)</td></tr>
<tr class="even">
<td class="flag_name">fwd</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Load Forwarding (L2L) and Store Forwarding (S2L)</td></tr>
<tr class="odd">
<td class="flag_name">dse</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Dead-Store Elimination</td></tr>
<tr class="even">
<td class="flag_name">abc</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Array Bounds Check Elimination</td></tr>
<tr class="odd">
<td class="flag_name">sink</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Allocation/Store Sinking</td></tr>
<tr class="even">
<td class="flag_name">fuse</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Fusion of operands into instructions</td></tr>
<tr class="odd">
<td class="flag_name">fma </td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_desc">Fused multiply-add</td></tr>
</table>
<p>
Here are the parameters and their default settings:
</p>
<table class="opt">
<tr class="opthead">
<td class="param_name">Parameter</td>
<td class="param_default">Default</td>
<td class="param_desc">&nbsp;</td>
</tr>
<tr class="odd separate">
<td class="param_name">maxtrace</td><td class="param_default">1000</td><td class="param_desc">Max. number of traces in the cache</td></tr>
<tr class="even">
<td class="param_name">maxrecord</td><td class="param_default">4000</td><td class="param_desc">Max. number of recorded IR instructions</td></tr>
<tr class="odd">
<td class="param_name">maxirconst</td><td class="param_default">500</td><td class="param_desc">Max. number of IR constants of a trace</td></tr>
<tr class="even">
<td class="param_name">maxside</td><td class="param_default">100</td><td class="param_desc">Max. number of side traces of a root trace</td></tr>
<tr class="odd">
<td class="param_name">maxsnap</td><td class="param_default">500</td><td class="param_desc">Max. number of snapshots for a trace</td></tr>
<tr class="even separate">
<td class="param_name">hotloop</td><td class="param_default">56</td><td class="param_desc">Number of iterations to detect a hot loop or hot call</td></tr>
<tr class="odd">
<td class="param_name">hotexit</td><td class="param_default">10</td><td class="param_desc">Number of taken exits to start a side trace</td></tr>
<tr class="even">
<td class="param_name">tryside</td><td class="param_default">4</td><td class="param_desc">Number of attempts to compile a side trace</td></tr>
<tr class="odd separate">
<td class="param_name">instunroll</td><td class="param_default">4</td><td class="param_desc">Max. unroll factor for instable loops</td></tr>
<tr class="even">
<td class="param_name">loopunroll</td><td class="param_default">15</td><td class="param_desc">Max. unroll factor for loop ops in side traces</td></tr>
<tr class="odd">
<td class="param_name">callunroll</td><td class="param_default">3</td><td class="param_desc">Max. unroll factor for pseudo-recursive calls</td></tr>
<tr class="even">
<td class="param_name">recunroll</td><td class="param_default">2</td><td class="param_desc">Min. unroll factor for true recursion</td></tr>
<tr class="odd separate">
<td class="param_name">sizemcode</td><td class="param_default">32</td><td class="param_desc">Size of each machine code area in KBytes (Windows: 64K)</td></tr>
<tr class="even">
<td class="param_name">maxmcode</td><td class="param_default">512</td><td class="param_desc">Max. total size of all machine code areas in KBytes</td></tr>
</table>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2025
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>

134
doc/running.md Normal file
View File

@ -0,0 +1,134 @@
# Running LuaJIT
LuaJIT has only a single stand-alone executable, called `luajit` on POSIX systems or `luajit.exe` on Windows. It can be used to run simple Lua statements or whole Lua applications from the command line. It has an interactive mode, too.
## Command Line Options
The `luajit` stand-alone executable is just a slightly modified version of the regular `lua` stand-alone executable. It supports the same basic options, too. `luajit -h` prints a short list of the available options. Please have a look at the [» Lua manual](https://www.lua.org/manual/5.1/manual.html#6) for details.
LuaJIT has some additional options:
### `-b[options] input output`
This option saves or lists bytecode. The following additional options
are accepted:
- `-l` — Only list bytecode.
- `-s` — Strip debug info (this is the default).
- `-g` — Keep debug info.
- `-W` — Generate 32 bit (non-GC64) bytecode.
- `-X` — Generate 64 bit (GC64) bytecode.
- `-d` — Generate bytecode in deterministic manner.
- `-n name` — Set module name (default: auto-detect from input name)
- `-t type` — Set output file type (default: auto-detect from output name).
- `-a arch` — Override architecture for object files (default: native).
- `-o os` — Override OS for object files (default: native).
- `-F name` — Override filename (default: input filename).
- `-e chunk` — Use chunk string as input.
- `-` (a single minus sign) — Use stdin as input and/or stdout as output.
The output file type is auto-detected from the extension of the output
file name:
- `c` — C source file, exported bytecode data.
- `cc` — C++ source file, exported bytecode data.
- `h` — C/C++ header file, static bytecode data.
- `obj` or `o` — Object file, exported bytecode data (OS and architecture-specific).
- `raw` or any other extension — Raw bytecode file (portable).
Notes:
- See also [string.dump()](./extensions#stringdumpf-mode-generates-portable-bytecode) for information on bytecode portability and compatibility.
- A file in raw bytecode format is auto-detected and can be loaded like any Lua source file. E.g. directly from the command line or with `loadfile()`, `dofile()` etc.
- To statically embed the bytecode of a module in your application, generate an object file and just link it with your application.
- On most ELF-based systems (e.g. Linux) you need to explicitly export the global symbols when linking your application, e.g. with: `-Wl,-E`
- `require()` tries to load embedded bytecode data from exported symbols (in `*.exe` or `lua51.dll` on Windows) and from shared libraries in `package.cpath`.
Typical usage examples:
```sh
# Save bytecode to test.out
luajit -b test.lua test.out
# Keep debug info
luajit -bg test.lua test.out
# Save cmdline script
luajit -be "print('hello world')" test.out
# List to stdout
luajit -bl test.lua
# List to test.txt
luajit -bl test.lua test.txt
# List cmdline script
luajit -ble "print('hello world')"
# Generate object file
luajit -b test.lua test.obj
# Link test.obj with your application and load it with require("test")
```
### `-j cmd[=arg[,arg...]]`
This option performs a LuaJIT control command or activates one of the
loadable extension modules. The command is first looked up in the
`jit.*` library. If no matching function is found, a module named
`jit.<cmd>` is loaded and the `start()` function of the module is called
with the specified arguments (if any). The space between `-j` and `cmd`
is optional.
Here are the available LuaJIT control commands:
- `-jon`: Turns the JIT compiler on (default).
- `-joff`: Turns the JIT compiler off (only use the interpreter).
- `-jflush`: Flushes the whole cache of compiled code.
- `-jv`: Shows verbose information about the progress of the JIT compiler.
- `-jdump`: Dumps the code and structures used in various compiler stages.
- `-jp`: Start the [integrated profiler](./ext_profiler).
The `-jv` and `-jdump` commands are extension modules written in Lua. They are mainly used for debugging the JIT compiler itself. For a description of their options and output format, please read the comment block at the start of their source. They can be found in the `lib` directory of the source distribution or installed under the `jit` directory. By default, this is `/usr/local/share/luajit-XX.YY.ZZ>/jit` on POSIX systems (replace XX.YY.ZZ by the installed version).
### `-O[level]` `-O[+]flag` `-O-flag` `-Oparam=value`
This options allows fine-tuned control of the optimizations used by the JIT compiler. This is mainly intended for debugging LuaJIT itself. Please note that the JIT compiler is extremely fast (we are talking about the microsecond to millisecond range). Disabling optimizations doesn't have any visible impact on its overhead, but usually generates code that runs slower.
The first form sets an optimization level — this enables a specific mix of optimization flags. `-O0` turns off all optimizations and higher numbers enable more optimizations. Omitting the level (i.e. just `-O`) sets the default optimization level, which is `-O3` in the current version.
The second form adds or removes individual optimization flags. The third form sets a parameter for the VM or the JIT compiler to a specific value.
You can either use this option multiple times (like `-Ocse -O-dce -Ohotloop=10`) or separate several settings with a comma (like `-O+cse,-dce,hotloop=10`). The settings are applied from left toright, and later settings override earlier ones. You can freely mix the three forms, but note that setting an optimization level overrides all earlier flags.
Note that `-Ofma` is not enabled by default at any level, because it affects floating-point result accuracy. Only enable this, if you fully understand the trade-offs of FMA for performance (higher), determinism (lower) and numerical accuracy (higher).
Here are the available flags and at what optimization levels they are enabled:
Flag | -O1 | -O2 | -O3 | Description
-------|-----|-----|-----|-------------
fold | • | • | • | Constant Folding, Simplifications and Reassociation
cse | • | • | • | Common-Subexpression Elimination
dce | • | • | • | Dead-Code Elimination
narrow |   | • | • | Narrowing of numbers to integers
loop |   | • | • | Loop Optimizations (code hoisting)
fwd |   |   | • | Load Forwarding (L2L) and Store Forwarding (S2L)
dse |   |   | • | Dead-Store Elimination
abc |   |   | • | Array Bounds Check Elimination
sink |   |   | • | Allocation/Store Sinking
fuse |   |   | • | Fusion of operands into instructions
fma |   |   |   | Fused multiply-add
Here are the parameters and their default settings:
Parameter | Default | Description
-----------|---------|-------------
maxtrace | 1000 | Max. number of traces in the cache
maxrecord | 4000 | Max. number of recorded IR instructions
maxirconst | 500 | Max. number of IR constants of a trace
maxside | 100 | Max. number of side traces of a root trace
maxsnap | 500 | Max. number of snapshots for a trace
hotloop | 56 | Number of iterations to detect a hot loop or hot call
hotexit | 10 | Number of taken exits to start a side trace
tryside | 4 | Number of attempts to compile a side trace
instunroll | 4 | Max. unroll factor for instable loops
loopunroll | 15 | Max. unroll factor for loop ops in side traces
callunroll | 3 | Max. unroll factor for pseudo-recursive calls
recunroll | 2 | Min. unroll factor for true recursion
sizemcode | 32 | Size of each machine code area in KBytes (Windows: 64K)
maxmcode | 512 | Max. total size of all machine code areas in KBytes