Lua

The LuaJIT Wiki

not logged in | [Login]

All aspects of Lua are implemented in LuaJIT's interpreter, but not all of them are implemented in LuaJIT's JIT compiler. This page serves as a quick reference to identify whether certain things are implemented or not. Hopefully meaning that you can avoid them in performance-critical code rather than puzzle over why you're seeing poorly performing code and NYI messages from -jv.

Note that the goal of LuaJIT is not only to produce fast code, but to have a fast and compact JIT compiler, too. It's not a stated goal to compile everything, since the interpreter is fast enough for many tasks. And speed doesn't matter for anything that's done only a couple of times during the runtime of a program. E.g. it would be absolutely pointless to compile require() or module() (in fact, these should eventually be rewritten as plain Lua functions).

However, the number of JIT-compiled cases will grow over time, based on demand and user feedback.

The following tables provide an indication whether a feature is JIT-compiled or not:

  • yes - Always JIT-compiled.
  • partial - May be JIT-compiled, depending on the circumstances. Otherwise will fall back to the interpreter or stitch.
  • bytecode - The function was implemented with lua code in LuaJIT 2.1. (Example)
  • 2.1 - Compiled starting with LuaJIT 2.1.
  • no - Not JIT-compiled (yet), will always fall back to the interpreter.
  • never - Ditto. Will not be JIT-compiled, even in future versions.

Bytecode

Almost all bytecodes are compiled, except for these:

Bytecode Compiled? Remarks
CAT 2.1 Concatenation operator '..'.
FNEW no Create closure.
FUNCC 2.1 stitch Call C function via classic API.
FUNCCW 2.1 stitch Call wrapped C function via classic API.
FUNC* partial Call built-in function. See below.
ISNEXT no Check for next() loop optimization. If the value is `next` function it's NYI, otherwise no.
ITERN no Optimized call to next() in loop.
IFORL no Interpreter-forced call to FORL instruction.
IITERL no Interpreter-forced call to ITERL instruction.
ILOOP no Interpreter-forced call to LOOP instruction.
IFUNCF no Interpreter-forced call to FUNCF instruction.
IFUNCV no Interpreter-forced call to FUNCV instruction.
CALLT partial Tailcall. Some tailcalls to frames lower than the starting frame of the trace are not compiled.
RET* partial Return from function. Returns to C frames and some returns to frames lower than the starting frame of the trace are not compiled.
TSETM 2.1 Initialize table with multiple return values.
UCLO no Close upvalues.
VARG partial Vararg operator '...'. Multi-result VARG is only compiled when used with select() (and with a const positive number).

Notes:

  • Table accesses to mixed dense/sparse tables are not compiled.
  • Bytecode execution that would cause an error in the interpreter is never compiled.
  • LuaJIT 2.1 adds a trace stitching feature which allows traces to stop at a classic C function or a not-compiled built-in, return to the interpreter, run the C function or built-in and then start a new trace after it returns. This is not particularly efficient, but it avoids trace aborts due to NYI functions, which would previously force the whole code path around such a function to be interpreted.

You will see bytecode numbers in your -jv output. You can use this bcname.lua script to convert them to their names or this:

$ # source: http://www.freelists.org/post/luajit/frames-and-tail-calls,1
$ cat >bcname.lua <<'END'
local x = tonumber(arg[1])
print(string.sub(require("jit.vmdef").bcnames, x*6+1, x*6+6))
END

$ luajit-2.1 bcname.lua 71
VARG

Libraries

The following tables list whether or not calls to the various built-in library functions will get compiled. This may depend on the arguments passed (esp. their types) and the exact circumstances of the call.

Base Library

Function Compiled? Remarks
assert yes
collectgarbage 2.1 stitch
gcinfo 2.1 stitch
dofile never 2.1 stitch
error never
getfenv 2.1 partial Only getfenv(0) is compiled.
getmetatable yes
ipairs yes
load never 2.1 stitch
loadfile never 2.1 stitch
loadstring never 2.1 stitch
newproxy 2.1 stitch
next 2.1 partial NYI if ISNEXT found this function in generic for loop, stitches otherwise.
pairs yes pairs by itself doesn't trigger NYI, see "next" function.
pcall yes
print partial NYI if error was caught. Always in 2.0, behaves different in 2.1. For example compiles if "error" function was called, but NYI if "assert" function was called, other exceptions apply.
rawequal yes
rawget yes
rawlen (5.2) yes
rawset yes
require 2.1 stitch
select partial Only compiled when first argument is a constant (Has to be positive if used with varg).
setfenv 2.1 stitch
setmetatable yes
tonumber partial Won't compile for bases other than 10, other exceptions apply.
tostring partial Only compiled for strings, numbers, booleans, nil, and values with a __tostring metamethod.
type yes
unpack 2.1 stitch
xpcall partial See "pcall".

String Buffer Library (2.1)

This library is a work in progress. More functions will be added soon. Nothing is compiled yet.

Function Compiled? Remarks
buffer.encode stitch
buffer.decode stitch

String Library

Function Compiled? Remarks
string.byte yes
string.char 2.1
string.dump never 2.1 stitch
string.find 2.1 partial Only plain string searches (no patterns).
string.format 2.1 partial Not for %p or non-string arguments for %s.
string.gmatch 2.1 stitch
string.gsub 2.1 stitch
string.len yes bytecode
string.lower 2.1
string.match 2.1 stitch
string.rep 2.1
string.reverse 2.1
string.sub yes
string.upper 2.1

Table Library

Function Compiled? Remarks
table.concat 2.1
table.foreach no bytecode NYI on ITERN
table.foreachi 2.1 bytecode
table.getn yes bytecode
table.insert partial Only when pushing.
table.maxn 2.1 stitch
table.pack (5.2) 2.1 stitch
table.remove 2.1 bytecode Partial in 2.0: only when popping.
table.move (5.3) yes bytecode
table.sort 2.1 stitch
table.unpack (5.2) 2.1 stitch

Math Library

Function Compiled? Remarks
math.abs yes
math.acos yes
math.asin yes
math.atan yes
math.atan2 yes
math.ceil yes
math.cos yes
math.cosh yes
math.deg yes bytecode
math.exp yes
math.floor yes
math.fmod 2.1 stitch
math.frexp 2.1 stitch
math.ldexp yes
math.log yes
math.log10 yes
math.max yes
math.min yes
math.modf yes
math.pow yes
math.rad yes bytecode
math.random yes
math.randomseed 2.1 stitch
math.sin yes
math.sinh yes
math.sqrt yes
math.tan yes
math.tanh yes

IO Library

Function Compiled? Remarks
io.close 2.1 stitch
io.flush yes
io.input 2.1 stitch
io.lines 2.1 stitch
io.open 2.1 stitch
io.output 2.1 stitch
io.popen 2.1 stitch
io.read 2.1 stitch
io.tmpfile 2.1 stitch
io.type 2.1 stitch
io.write yes

Bit Library

Function Compiled? Remarks
bit.arshift yes
bit.band yes
bit.bnot yes
bit.bor yes
bit.bswap yes
bit.bxor yes
bit.lshift yes
bit.rol yes
bit.ror yes
bit.rshift yes
bit.tobit yes
bit.tohex 2.1

FFI Library

Function Compiled? Remarks
ffi.alignof yes
ffi.abi yes
ffi.cast partial Same restrictions as ffi.new (casting is a form of cdata creation).
ffi.cdef never 2.1 stitch
ffi.copy yes
ffi.errno partial Not when setting a new value.
ffi.fill yes
ffi.gc 2.1 Partial in 2.0: not when clearing a finalizer.
ffi.istype yes
ffi.load never 2.1 stitch
ffi.metatype never 2.1 stitch
ffi.new partial 2.0: Not for VLA/VLS, > 8 byte alignment or > 128 bytes.
2.1: Not for non-default init of VLA/VLS or > 128 bytes or > 16 array elements.
ffi.offsetof yes
ffi.sizeof partial Not for VLA/VLS types (see below).
ffi.string yes
ffi.typeof partial Only for cdata arguments. Never for cdecl strings.

For more details see the current implementation status of the FFI library.

Note: Avoid ffi.sizeof(cdata) for variable-length types (VLA/VLS). This call is not compiled and may become a rather expensive operation with the New Garbage Collector, since the actual length may not be stored inside the cdata object anymore.

Coroutine Library

No functions are compiled. (Stitches on 2.1)

OS Library

No functions are compiled. (Stitches on 2.1)

Package Library

No functions are compiled (will be replaced with builtin bytecode). (Stitches on 2.1)

Debug Library

Function Compiled? Remarks
debug.getmetatable 2.1
debug.* no/never Unlikely to change

JIT Library

No functions are compiled (unlikely to change, except for possible future compiler hints). (Stitches on 2.1)