commit fb7e5b76c9d41108c399cf4d16470018b717007b
parent c1dc08e8e8e22af9902a6341b4a9a9a7811954cc
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 26 Jun 2024 14:46:17 -0300
Clearer code for controlling maximum registers
Plus, added a test to check that limit.
Diffstat:
3 files changed, 28 insertions(+), 10 deletions(-)
diff --git 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
@@ -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
@@ -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'