+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.
+
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
+is always performed on 64 bit integers.
+
Contains the version number of the LuaJIT core. Version xx.yy.zz
-is represented by the decimal number xxyyzz.
+is represented by the decimal number xxyyzz.
+DEPRECATED after the switch to
+» rolling releases. zz is frozen at 99.
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.
+
An extra argument has been added to string.dump(). If set to
-true, 'stripped' bytecode without debug information is
-generated. This speeds up later bytecode loading and reduces memory
-usage. See also the
+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.
The generated bytecode is portable and can be loaded on any architecture
-that LuaJIT supports, independent of word size or endianess. However, the
-bytecode compatibility versions must match. Bytecode stays compatible
-for dot releases (x.y.0 → x.y.1), but may change with major or
-minor releases (2.0 → 2.1) or between any beta release. Foreign
-bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
+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 for all 64 bit ports. This may be
-rectified in the future.
+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
+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
@@ -239,7 +265,7 @@
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().
+implementation, which uses the platform-specific ANSI rand().
The PRNG generates the same sequences from the same seeds on all
@@ -250,6 +276,10 @@
Enhanced PRNG for math.random()
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.
@@ -287,7 +317,7 @@
Extensions from Lua 5.2
goto and ::labels::.
-
Hex escapes '\x3F' and '\*' escape in strings.
+
Hex escapes '\x3F' and '\z' escape in strings.
load(string|reader [, chunkname [,mode [,env]]]).
loadstring() is an alias for load().
loadfile(filename [,mode [,env]]).
@@ -427,9 +457,7 @@
C++ Exception Interoperability
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.
-For MSVC for Windows 64 bit this requires compilation of your C++ code
-with /EHa.
+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.
-LuaJIT is only distributed as a source package. This page explains
-how to build and install LuaJIT with different operating systems
-and C compilers.
+LuaJIT is only distributed as source code — get it from the
+» git repository. This page explains how to build
+and install the LuaJIT binary and library for different operating systems.
For the impatient (on POSIX systems):
@@ -92,201 +90,21 @@
Installation
Requirements
-
Systems
-LuaJIT currently builds out-of-the box on most systems:
+LuaJIT currently builds out-of-the box on most systems. Please check the
+supported operating systems and CPU architectures on the
+» status page.
-The codebase has compatibility defines for some more systems, but
-without official support.
-
-
Toolchains
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.
-
CPU Architectures
-
-
-
CPU
-
Bits
-
Requirements
-
Variants
-
LuaJIT Versions
-
-
-
x86
-
32
-
v2.1+: SSE2
-
-
v2.0 –
-
-
-
x64
-
64
-
-
-
v2.0 –
-
-
-
ARM
-
32
-
ARMv5+, ARM9E+
-
hard-fp + soft-fp
-
v2.0 –
-
-
-
ARM64
-
64
-
-
ARM64le + ARM64be
-
v2.1 –
-
-
-
PPC32
-
32
-
-
hard-fp + soft-fp
-
v2.0 – v2.1 EOL
-
-
-
PPC/e500
-
32
-
e500v2
-
-
v2.0 EOL
-
-
-
MIPS32
-
32
-
MIPS32r1 – r5
-
hard-fp + soft-fp
-
v2.0 –
-
-
-
MIPS64
-
64
-
MIPS64r1 – r5
-
hard-fp + soft-fp
-
v2.1 –
-
-
-
MIPS64
-
64
-
MIPS64r6
-
hard-fp + soft-fp
-
v2.1 EOL
-
-
-
RISC-V
-
64
-
RVA22+
-
-
TBA
-
-
-There are no plans to add historic architectures or to continue support
-for end-of-life (EOL) architectures, for which no new CPUs are commonly
-available anymore. Likewise, there are no plans to support marginal
-and/or de-facto-dead architectures.
+Batch files are provided for MSVC++ builds and console cross-builds.
Configuring LuaJIT
@@ -296,7 +114,6 @@
Configuring LuaJIT
hold all user-configurable settings:
-
src/luaconf.h sets some configuration variables.
Makefile has settings for installing LuaJIT (POSIX
only).
src/Makefile has settings for compiling LuaJIT
@@ -319,23 +136,11 @@
Configuring LuaJIT
POSIX Systems (Linux, macOS, *BSD etc.)
Prerequisites
-Depending on your distribution, you may need to install a package for
-GCC, the development headers and/or a complete SDK. E.g. on a current
-Debian/Ubuntu, install libc6-dev with the package manager.
+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.
-
-The recommended way to fetch the latest version is to do a pull from
-the git repository.
-
-
-Alternatively, download the latest source package of LuaJIT (pick the .tar.gz).
-Move it to a directory of your choice, open a terminal window and change
-to this directory. Now unpack the archive and change to the newly created
-directory (replace XX.YY.ZZ with the version you downloaded):
-
GCC plus the required development headers.
Or install Microsoft's Visual Studio (MSVC).
-
-Next, pull from the git repository or download the source package and
-unpack it using an archive manager (e.g. the Windows Explorer) to
-a directory of your choice.
-
Building with MSVC
-Open a "Visual Studio Command Prompt" (either x86 or x64), cd to the
-directory where you've unpacked the sources and run these commands:
+Open a "Visual Studio Command Prompt" (x86, x64 or ARM64), cd to the
+directory with the source code and run these commands:
cd src
@@ -414,11 +214,14 @@
Building with MSVC
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
-or where you've unpacked the sources. Then run this command for MinGW:
+are in your path. Then cd to the directory of the git repository.
+Then run this command for MinGW:
mingw32-make
@@ -466,6 +269,7 @@
Cross-compiling LuaJIT
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.
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 where you've
-unpacked the sources and run the build command given in the table:
+Then cd to the src directory below the source code
+and run the build command given in the table:
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. It scales from
-embedded devices, smartphones, desktops up to server farms. It combines
-high flexibility with high performance
-and an unmatched low memory footprint.
+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
@@ -222,7 +193,7 @@
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
@@ -107,10 +106,14 @@
-b[options] input output
-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.
@@ -120,7 +123,8 @@
-b[options] input output
c — C source file, exported bytecode data.
-
h — C header file, static 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).
@@ -221,6 +225,12 @@
-O[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:
@@ -252,6 +262,8 @@
-O[level]
sink
•
Allocation/Store Sinking
fuse
•
Fusion of operands into instructions
+
+
fma
Fused multiply-add
Here are the parameters and their default settings:
@@ -295,7 +307,7 @@
Q: Why do I get this error: "attempt to index global 'arg' (a nil value)"?
-Q: My vararg functions fail after switching to LuaJIT!
-
LuaJIT is compatible to the Lua 5.1 language standard. It doesn't
-support the implicit arg parameter for old-style vararg
-functions from Lua 5.0. Please convert your code to the
-» Lua 5.1
-vararg syntax.
-
-
-
-
Q: Why do I get this error: "bad FPU precision"?
-
Q: I get weird behavior after initializing Direct3D.
-
Q: Some FPU operations crash after I load a Delphi DLL.
-
-
-
-DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision
-mode by default. This violates the Windows ABI and interferes with the
-operation of many programs — LuaJIT is affected, too. Please make
-sure you always use the D3DCREATE_FPU_PRESERVE flag when
-initializing Direct3D.
-
-Direct3D version 10 or higher do not show this behavior anymore.
-Consider testing your application with older versions, too.
-
-Similarly, the Borland/Delphi runtime modifies the FPU control word and
-enables FP exceptions. Of course, this violates the Windows ABI, too.
-Please check the Delphi docs for the Set8087CW method.
-
-
-
-
Q: Sometimes Ctrl-C fails to stop my Lua program. Why?
-
The interrupt signal handler sets a Lua debug hook. But this is
-ignored by compiled code. If your program is running in a tight loop
-and never falls back to the interpreter, the debug hook never runs and
-can't throw the "interrupted!" error.
-You have to press Ctrl-C twice to stop your program. That's similar
-to when it's stuck running inside a C function under the Lua interpreter.
-
-
-
-
Q: Table iteration with pairs() does not result in the same order?
-
The order of table iteration is explicitly undefined by
-the Lua language standard.
-Different Lua implementations or versions may use different orders for
-otherwise identical tables. Different ways of constructing a table may
-result in different orders, too.
-Due to improved VM security, LuaJIT 2.1 may even use a different order
-on separate VM invocations or when string keys are newly interned.
-If your program relies on a deterministic order, it has a bug. Rewrite it,
-so it doesn't rely on the key order. Or sort the table keys, if you must.
-
-
-
-
Q: Can Lua code be safely sandboxed?
-
-Maybe for an extremely restricted subset of Lua and if you relentlessly
-scrutinize every single interface function you offer to the untrusted code.
-
-Although Lua provides some sandboxing functionality (setfenv(), hooks),
-it's very hard to get this right even for the Lua core libraries. Of course,
-you'll need to inspect any extension library, too. And there are libraries
-that are inherently unsafe, e.g. the FFI library.
-
-More reading material at the » Lua Wiki and » Wikipedia.
-
-Relatedly, loading untrusted bytecode is not safe!
-
-It's trivial to crash the Lua or LuaJIT VM with maliciously crafted bytecode.
-This is well known and there's no bytecode verification on purpose, so please
-don't report a bug about it. Check the mode parameter for the
-load*() functions to disable loading of bytecode.
-
-In general, the only promising approach is to sandbox Lua code at the
-process level and not the VM level.
-
-
-
-
-
Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?
-
Because it's a compiler — it needs to generate native
-machine code. This means the code generator must be ported to each
-architecture. And the fast interpreter is written in assembler and
-must be ported, too. This is quite an undertaking.
-The install documentation shows the supported
-architectures.
-Other architectures may follow based on sufficient user demand and
-market-relevance of the architecture. Sponsoring is required to develop
-the port itself, to integrate it and to continuously maintain it in the
-actively developed branches.
-This documentation is for LuaJIT 2.1.0-beta3. Please check the doc
-directory in each git branch for the version-specific documentation.
-
-
-The currently developed branches are LuaJIT 2.1 and LuaJIT 2.0.
-
-
-LuaJIT 2.0 is in feature-freeze — new features will only
-be added to LuaJIT 2.1.
-
-
-
Current Status
-
-LuaJIT ought to run all Lua 5.1-compatible source code just fine.
-It's considered a serious bug if the VM crashes or produces unexpected
-results — please report this.
-
-
-Known incompatibilities and issues in LuaJIT 2.0:
-
-
-
-There are some differences in implementation-defined behavior.
-These either have a good reason, are arbitrary design choices,
-or are due to quirks in the VM. The latter cases may get fixed if a
-demonstrable need is shown.
-
-
-The Lua debug API is missing a couple of features (return
-hooks for non-Lua functions) and shows slightly different behavior
-in LuaJIT (no per-coroutine hooks, no tail call counting).
-