The document discusses the Lua virtual machine (LuaVM) bytecode format and instructions. It shows an example Lua function written in bytecode format, with each instruction taking up one bytecode. The bytecode format uses registers to reference values on the stack and constants to reference values in the constant table. Common Lua operations like variable assignment and table indexing can be represented in a single bytecode instruction this way.
6. I think that one cannot completely grok a
scripting language, or any complex system for
that matter, without slitting the animal open
and examining the entrails, organs and other
yucky stuff that isn’t normally seen.
2010 2 24
11. /*----------------------------------------------------------------------
38 (5.1.4 ) name args description
------------------------------------------------------------------------*/
OP_MOVE,/* A B R(A) := R(B) */
OP_LOADK,/* A Bx R(A) := Kst(Bx) */
OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
R(X) X OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
OP_GETUPVAL,/* A B R(A) := UpValue[B] */
OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)]
*/
OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */
OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
K(X) X OP_SUB,/*
OP_MUL,/*
A B C R(A) := RK(B) - RK(C)
A B C R(A) := RK(B) * RK(C)
*/
*/
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */
OP_LEN,/* A B R(A) := length of R(B) */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
RK(X) R(X) OP_JMP,/*
OP_EQ,/*
OP_LT,/*
sBx pc+=sBx
A B C if ((RK(B) == RK(C)) ~= A) then pc++
A B C if ((RK(B) < RK(C)) ~= A) then pc++
*/
*/
*/
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
K(X-k) OP_TEST,/* A C if not (R(A) <=> C) then pc++
OP_TESTSET,/*
*/
A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
2010 2 24
12. /*----------------------------------------------------------------------
38 (5.1.4 ) name args description
------------------------------------------------------------------------*/
OP_MOVE,/* A B R(A) := R(B) */
OP_LOADK,/* A Bx R(A) := Kst(Bx) */
OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
R(X) X OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
OP_GETUPVAL,/* A B R(A) := UpValue[B] */
OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)]
*/
OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */
OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
K(X) X OP_SUB,/*
OP_MUL,/*
A B C R(A) := RK(B) - RK(C)
A B C R(A) := RK(B) * RK(C)
*/
*/
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */
OP_LEN,/* A B R(A) := length of R(B) */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
RK(X) R(X) OP_JMP,/*
OP_EQ,/*
OP_LT,/*
sBx pc+=sBx
A B C if ((RK(B) == RK(C)) ~= A) then pc++
A B C if ((RK(B) < RK(C)) ~= A) then pc++
*/
*/
*/
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
K(X-k) OP_TEST,/* A C if not (R(A) <=> C) then pc++
OP_TESTSET,/*
*/
A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
2010 2 24
14. NEWTABLE
SELF
ADD
SUB
MUL
DIV
MOD
POW
UNM
NOT
2010 2 24
15. LEN
CONCAT
JMP
EQ
LT
LE
TEST
TESTSET
CALL
TAILCALL
2010 2 24
16. RETURN
FORLOOP for FORPREP
FORPREP for
TFORLOOP for
SETLIST
CLOSE
CLOSURE
VARARG
2010 2 24
17. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
OP A B C
OP A Bx
OP A sBx
Figure 6: Instruction layout
OP 6bit
function max (a,b)
local m = a 1 MOVE 2 0 0 ; R(2) = R(0)
if b > a then 2 LT 0 0 1 ; R(0) < R(1) ?
m = b
end
3
4
A
JMP
MOVE
1
2 1 0
;
;
8bit
to 5 (4+1)
R(2) = R(1)
return m 5 RETURN 2 2 0 ; return R(2)
end 6 B C 9bit
RETURN 0 1 0 ; return
18bit 7: Bytecode for a Lua function
Figure
Bx(unsigned) or sBx(signed)
a register or a constant (using the representation RK(X) explained above). With
this format, several typical operations in Lua can be coded in a single instruction.
2010 2 24
18. OP A Bx
OP A sBx
Figure 6: Instruction layout
function max (a,b)
local m = a 1 MOVE 2 0 0 ; R(2) = R(0)
if b > a then 2 LT 0 0 1 ; R(0) < R(1) ?
m = b 3 JMP 1 ; to 5 (4+1)
end 4 MOVE 2 1 0 ; R(2) = R(1)
return m 5 RETURN 2 2 0 ; return R(2)
end 6 RETURN 0 1 0 ; return
Figure 7: Bytecode for a Lua function
a register or a constant (using the representation RK(X) explained above). With
this format, several typical operations in Lua can be coded in a single instruction.
For instance, the increment of a local variable, such as a = a + 1, is coded
as ADD x x y, where x represents the register holding the local variable and y
represents the constant 1. An assignment like a = b.f, when both a and b are
local variables, is also coded as the single instruction GETTABLE x y z, where x
is the register for a, y is the register for b, and z is the index of the string
constant "f". (In Lua, the syntax b.f is syntactic sugar for b["f"], that is, b
2010 2 24 indexed by the string "f".)
19. OP A Bx
OP A sBx
Figure 6: Instruction layout
function max (a,b)
local m = a 1 MOVE 2 0 0 ; R(2) = R(0)
if b > a then 2 LT 0 0 1 ; R(0) < R(1) ?
m = b 3 JMP 1 ; to 5 (4+1)
end 4 MOVE 2 1 0 ; R(2) = R(1)
return m 5 RETURN 2 2 0 ; return R(2)
end 6 RETURN 0 1 0 ; return
Figure 7: Bytecode for a Lua function
R(0) == a, R(1) == b
a register or a constant (using the representation RK(X) explained above). With
this format, several typical operations in Lua can be coded in a single instruction.
LT For instance, the increment of a local variable, such as a = a + 1, is coded
as ADD x x y, where x represents the register holding the local variable and y
PC++ JMP
represents the constant 1. An assignment like a = b.f, when both a and b are
local variables, is also coded as the single instruction GETTABLE x y z, where x
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++
is the register for a, y is the register for b, and z is the index of the string
constant "f". (In Lua, the syntax b.f is syntactic sugar for b["f"], that is, b
*/
2010 2 24 indexed by the string "f".)
53. ual machine with the new optimization for arrays can reduce the runnin
up to 40%.
The complete code of Lua 5.0 is available for browsing at Lua’s web site
p://www.lua.org/source/5.0/.
program Lua 4.0 Lua 5’ Lua 5.0
sum (2e7) 1.23 0.54 (44%) 0.54 (44%)
fibo (30) 0.95 0.68 (72%) 0.69 (73%)
ack (8) 1.00 0.86 (86%) 0.88 (88%)
random (1e6) 1.04 0.96 (92%) 0.96 (92%)
sieve (100) 0.93 0.82 (88%) 0.57 (61%)
heapsort (5e4) 1.08 1.05 (97%) 0.70 (65%)
matrix (50) 0.84 0.82 (98%) 0.59 (70%)
re 10: Benchmarks (times in seconds; percentages are relative to Lua 4.0)
Lua
2010 2 24
57. LuaVM
Lua-Alchemy(Lua on Flash)
kahlua(Lua on Java[J2ME])
Yueliang(Lua on Lua)
LuaCLR(Lua on .NET)
Lua2js(Lua on JavaScript)
http://lua-users.org/wiki/
LuaImplementations
2010 2 24
58. The Implementation of Lua 5.0
The Evolution of Lua
A No-Frills Introduction to Lua 5.1 VM
Instructions
Lua lvm.c lopcodes.h
2010 2 24