Clearer code for controlling maximum registers

Plus, added a test to check that limit.
This commit is contained in:
Roberto Ierusalimschy 2024-06-26 14:46:44 -03:00
parent c1dc08e8e8
commit fb7e5b76c9
3 changed files with 28 additions and 10 deletions

View File

@ -31,10 +31,6 @@
#include "lvm.h" #include "lvm.h"
/* Maximum number of registers in a Lua function (must fit in 8 bits) */
#define MAXREGS 255
#define hasjumps(e) ((e)->t != (e)->f) #define hasjumps(e) ((e)->t != (e)->f)
@ -466,7 +462,7 @@ static int luaK_codek (FuncState *fs, int reg, int k) {
void luaK_checkstack (FuncState *fs, int n) { void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs->freereg + n; int newstack = fs->freereg + n;
if (newstack > fs->f->maxstacksize) { if (newstack > fs->f->maxstacksize) {
if (newstack >= MAXREGS) if (newstack > MAX_FSTACK)
luaX_syntaxerror(fs->ls, luaX_syntaxerror(fs->ls,
"function or expression needs too many registers"); "function or expression needs too many registers");
fs->f->maxstacksize = cast_byte(newstack); fs->f->maxstacksize = cast_byte(newstack);

View File

@ -23,9 +23,9 @@ iAsBx sBx (signed)(17) | A(8) | Op(7) |
iAx Ax(25) | Op(7) | iAx Ax(25) | Op(7) |
isJ sJ (signed)(25) | Op(7) | isJ sJ (signed)(25) | Op(7) |
A signed argument is represented in excess K: the represented value is A signed argument is represented in excess K: The represented value is
the written unsigned value minus K, where K is half the maximum for the the written unsigned value minus K, where K is half (rounded down) the
corresponding unsigned argument. maximum value for the corresponding unsigned argument.
===========================================================================*/ ===========================================================================*/
@ -177,9 +177,16 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */
/* /*
** invalid register that fits in 8 bits ** Maximum size for the stack of a Lua function. It must fit in 8 bits.
** The highest valid register is one less than this value.
*/ */
#define NO_REG MAXARG_A #define MAX_FSTACK MAXARG_A
/*
** Invalid register (one more than last valid register).
*/
#define NO_REG MAX_FSTACK
/* /*

View File

@ -445,5 +445,20 @@ do -- string constants
assert(T.listk(f2)[1] == nil) assert(T.listk(f2)[1] == nil)
end end
do -- check number of available registers
-- 1 register for local + 1 for function + 252 arguments
local source = "local a; return a(" .. string.rep("a, ", 252) .. "a)"
local prog = T.listcode(assert(load(source)))
-- maximum valid register is 254
for i = 1, 254 do
assert(string.find(prog[2 + i], "MOVE%s*" .. i))
end
-- one more argument would need register #255 (but that is reserved)
source = "local a; return a(" .. string.rep("a, ", 253) .. "a)"
local _, msg = load(source)
assert(string.find(msg, "too many registers"))
end
print 'OK' print 'OK'