Skip to content

Commit

Permalink
Massively simplify luaK_prepcallfirstarg on the assumption that 'func…
Browse files Browse the repository at this point in the history
…' is actually not in a register yet, hence we can discharge it into a VRELOC, and put it directly in the correct register. Managing 'e' is also not a PITA under this assumption because we don't have to worry about the function being overwritten.
  • Loading branch information
Sainan committed Dec 16, 2023
1 parent e2da5ff commit 2a6b326
Showing 1 changed file with 6 additions and 38 deletions.
44 changes: 6 additions & 38 deletions src/lcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1104,44 +1104,12 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
** Convert expression 'e' into 'func(e,'.
*/
void luaK_prepcallfirstarg (FuncState *fs, expdesc *e, expdesc *func) {
luaK_exp2anyreg(fs, func);
int freg = func->u.reg; /* register where 'func' was placed */
if (e->k == VNIL || e->k == VFALSE || e->k == VTRUE || e->k == VKSTR || e->k == VK || e->k == VKFLT || e->k == VKINT || e->k == VRELOC) { /* 'e' is yet to be loaded into a register? */
freeexp(fs, func);
const int basereg = fs->freereg; /* base register for call */
exp2reg(fs, e, basereg + 1);
luaK_reserveregs(fs, 2); /* function and first arg */
if (basereg != freg) { /* ensure function is in correct register */
luaK_codeABC(fs, OP_MOVE, basereg, freg, 0);
}
e->u.reg = basereg;
e->k = VNONRELOC; /* expression has a fixed register */
}
else {
luaK_exp2anyreg(fs, e);
int ereg = e->u.reg; /* register where 'e' was placed */
freeexps(fs, e, func);
e->u.reg = fs->freereg; /* base register for call */
e->k = VNONRELOC; /* expression has a fixed register */
luaK_reserveregs(fs, 2); /* function and first arg */
if (ereg == e->u.reg) { /* argument is in the register where the function should be? */
if (freg == e->u.reg + 1) { /* function is in the register where the argument should be? */
/* oh dear. we have to swap them around. move function into a temporary register. */
luaK_checkstack(fs, 1);
int tmpreg = e->u.reg + 2;
luaK_codeABC(fs, OP_MOVE, tmpreg, freg, 0);
freg = tmpreg;
}
luaK_codeABC(fs, OP_MOVE, e->u.reg + 1, ereg, 0); /* move it where it should be */
ereg = e->u.reg + 1; /* and don't do it again */
}
if (e->u.reg != freg) { /* ensure function is in correct register */
luaK_codeABC(fs, OP_MOVE, e->u.reg, freg, 0);
}
if (e->u.reg + 1 != ereg) { /* ensure argument is in correct register */
luaK_codeABC(fs, OP_MOVE, e->u.reg + 1, ereg, 0);
}
}
luaK_reserveregs(fs, 2); /* function and first arg */
const int basereg = fs->freereg; /* base register for call */
luaK_exp2reg(fs, e, basereg + 1);
luaK_exp2reg(fs, func, basereg);
e->u.reg = basereg;
e->k = VNONRELOC; /* expression has a fixed register */
}


Expand Down

0 comments on commit 2a6b326

Please sign in to comment.