diff --git a/lcode.c b/lcode.c index 79c15132..bc0a3341 100644 --- a/lcode.c +++ b/lcode.c @@ -31,10 +31,6 @@ #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) @@ -466,7 +462,7 @@ static int luaK_codek (FuncState *fs, int reg, int k) { void luaK_checkstack (FuncState *fs, int n) { int newstack = fs->freereg + n; if (newstack > fs->f->maxstacksize) { - if (newstack >= MAXREGS) + if (newstack > MAX_FSTACK) luaX_syntaxerror(fs->ls, "function or expression needs too many registers"); fs->f->maxstacksize = cast_byte(newstack); diff --git a/lopcodes.h b/lopcodes.h index 6d888042..235c51f6 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -23,9 +23,9 @@ iAsBx sBx (signed)(17) | A(8) | Op(7) | iAx Ax(25) | Op(7) | isJ sJ (signed)(25) | Op(7) | - 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 - corresponding unsigned argument. + A signed argument is represented in excess K: The represented value is + the written unsigned value minus K, where K is half (rounded down) the + 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 + /* diff --git a/testes/code.lua b/testes/code.lua index bd4b10d0..329619f1 100644 --- a/testes/code.lua +++ b/testes/code.lua @@ -445,5 +445,20 @@ do -- string constants assert(T.listk(f2)[1] == nil) 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'