Lua

LuaJIT is fully upwards-compatible with Lua 5.1. It supports all » standard Lua library functions and the full set of » Lua/C API functions.

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.

bit.* — Bitwise Operations

LuaJIT supports all bitwise operations as defined by » Lua BitOp:

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.

Please make sure to require the module before using any of its functions:

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.

jit.* — JIT compiler control

The functions in this built-in module control the behavior of the JIT compiler engine.

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 subfunctions of a function. With false only the subfunctions 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.

status = jit.flush(tr)

Tries to flush the code for the specified trace and all of its side traces from the cache. Returns true on success. Returns false if there are still links to this trace.

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.

jit.arch

Contains the target architecture name (CPU and optional ABI).

jit.opt.* — JIT compiler optimization control

This module provides the backend for the -O command line option.

You can also use it programmatically, e.g.:

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 module 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.

C API extensions

LuaJIT adds some extensions to the Lua/C API. The LuaJIT include directory must be in the compiler search path (-Ipath) to be able to include the required header for C code:

#include "luajit.h"

Or 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:

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 on, LUAJIT_MODE_ON to turn a feature off, 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 subfunctions of the function with LUAJIT_MODE_ALLFUNC or only to the subfunctions with LUAJIT_MODE_ALLSUBFUNC.

luaJIT_setmode(L, trace,
  LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)

Tries to flush the code for the specified trace and all of its side traces from the cache.

luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)

This mode defines a wrapper function for calls to C functions. The first time this is called with LUAJIT_MODE_ON, the stack index at idx must be a lightuserdata object holding a pointer to the wrapper function. All subsequently created C functions are called through the wrapper functions. After the initial definition idx can be left at 0 when turning the mode on or off.

The wrapper function can be used for debugging purposes or to catch and convert foreign exceptions. Recommended usage can be seen in this C++ code excerpt:

#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 {
    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 myregister(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);
  luaL_register(L, "mymodule", myfuncs);  // Pass luaL_Reg list.
  luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_OFF);
  ...
  // Wrap some more C++ functions which might throw an exception.
  luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
  lua_pushcfunction(L, mythrowingfunc1);
  lua_pushcclosure(L, mythrowingfunc2, 1);
  luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_OFF);
  ...
}

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. It should only be enabled for definitions of C++ functions that can actually throw exceptions. If you're embedding LuaJIT into an application, only enable it after running luaL_openlibs.

LuaJIT already intercepts exception handling for all x64 systems and for x86 systems using DWARF2 stack unwinding (e.g. Linux, OSX). This is a zero-cost mechanism and always enabled. You don't need to use any wrapper functions, except when you want to get a more specific error message than "C++ exception".