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


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.
ITERN no Optimized call to next() in loop.
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().


  • 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:,1
$ cat >bcname.lua <<'END'
local x = tonumber(arg[1])
print(string.sub(require("jit.vmdef").bcnames, x*6+1, x*6+6))

$ luajit-2.1 bcname.lua 71


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 no
dofile never
error never
getfenv 2.1 partial Only getfenv(0) is compiled.
getmetatable yes
ipairs yes
load never
loadfile never
loadstring never
next no
pairs no
pcall yes
print no
rawequal yes
rawget yes
rawlen (5.2) yes
rawset yes
select partial Only compiled when first argument is a constant.
setfenv no
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 no
xpcall yes

String Library

Function Compiled? Remarks
string.byte yes
string.char 2.1
string.dump never
string.find 2.1 partial Only fixed string searches (no patterns).
string.format 2.1 partial Not for %p or non-string arguments for %s.
string.gmatch no
string.gsub no
string.len yes
string.lower 2.1
string.match no
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 2.1: builtin compiled, but NYI on ITERN
table.foreachi 2.1
table.getn yes
table.insert partial Only when pushing.
table.maxn no
table.pack (5.2) no
table.remove 2.1 Partial in 2.0: only when popping.
table.sort no
table.unpack (5.2) no

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
math.exp yes
math.floor yes
math.fmod no
math.frexp no
math.ldexp yes
math.log yes
math.log10 yes
math.max yes
math.min yes
math.modf yes
math.pow yes
math.rad yes
math.random yes
math.randomseed no
math.sin yes
math.sinh yes
math.sqrt yes
math.tan yes
math.tanh yes

IO Library

Function Compiled? Remarks
io.close no
io.flush yes
io.input no
io.lines no no
io.output no
io.popen no no
io.tmpfile no
io.type no
io.write yes

Bit Library

Function Compiled? Remarks
bit.arshift yes 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 (casting is a form of cdata creation).
ffi.cdef never
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
ffi.metatype never 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.

OS Library

No functions are compiled.

Package Library

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

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