lua-users home
lua-l archive

Re: about lua51 lcode.c code design

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> I'm reading the source code of lua515, there is some code then I
> don't understand yet
> 
> int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
> luaK_dischargevars(fs, e);
> if (e->k == VNONRELOC) {
> if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register
> */
> if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
> exp2reg(fs, e, e->u.s.info); /* put value on it */
> return e->u.s.info;
> }
> }
> luaK_exp2nextreg(fs, e); /* default */
> return e->u.s.info;
> }
> 
> Here is a branch "e->u.s.info >= fs->nactvar", I don't quite understand,
> can anyone explain the relevant context or example? thank you all.
As the comment explains, the test checks whether the register holds
a local variable. If it does, we cannot change its value, so we put
the value in the next available register (luaK_exp2nextreg). Otherwise,
the final value can live where it is.
As an example, consider the code below:
 local a1,a2
 do
 return (a1 or a2) + 1
 end
 do
 return a1 or (a2 + 1)
 end
It generates the follwoing opcodes. (This is 5.3, but the general idea
is the same.)
	1	[1]	LOADNIL 	0 1
	2	[3]	TESTSET 	2 0 1
	3	[3]	JMP 	0 1	; to 5
	4	[3]	MOVE 	2 1
	5	[3]	ADD 	2 2 -1	; - 1
	6	[3]	RETURN 	2 2
	7	[6]	TESTSET 	2 0 1
	8	[6]	JMP 	0 1	; to 10
	9	[6]	ADD 	2 1 -1	; - 1
	10	[6]	RETURN 	2 2
In the first case (lines 2-6), it cannot put the final result in
register 1, because it cannot change a2. So, it has to put the
result in register 2, and therefore needs a move (line 4). In
the second case, the results are already in register 2, which is
not a variable, so they stay there and there is no need for a move.
-- Roberto

AltStyle によって変換されたページ (->オリジナル) /