Consider the Lua script:
local a, b
a = 10
b = 30
b, a = a, b
Run luac -l
on it and you'll get this:
1 [1] LOADNIL 0 1
2 [2] LOADK 0 -1 ; 10
3 [3] LOADK 1 -2 ; 30
4 [4] MOVE 2 0
5 [4] MOVE 0 1
6 [4] MOVE 1 2
7 [4] RETURN 0 1
These are the instructions of the Lua VM for the given script. The local variables are assigned to registers 0 and 1 and then register 2 is used for the swap, much like you'd do manually using a temporary variable. In fact, the Lua script below generates exactly the same VM code:
local a, b
a = 10
b = 30
local c=a; a=b; b=c
The only difference is that the compiler would reuse register 2 in the first case if the script was longer and more complex.