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:
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:
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
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.
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 | |
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". |
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 |
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 |
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 |
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 |
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 |
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 |
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.
No functions are compiled. (Stitches on 2.1)
No functions are compiled. (Stitches on 2.1)
No functions are compiled (will be replaced with builtin bytecode). (Stitches on 2.1)
Function | Compiled? | Remarks |
---|---|---|
debug.getmetatable | 2.1 | |
debug.* | no/never | Unlikely to change |
No functions are compiled (unlikely to change, except for possible future compiler hints). (Stitches on 2.1)