Quellcode durchsuchen

Clearer code for controlling maximum registers

Plus, added a test to check that limit.
Roberto Ierusalimschy vor 1 Jahr
Ursprung
Commit
fb7e5b76c9
3 geänderte Dateien mit 28 neuen und 10 gelöschten Zeilen
  1. 1 5
      lcode.c
  2. 12 5
      lopcodes.h
  3. 15 0
      testes/code.lua

+ 1 - 5
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);

+ 12 - 5
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
+
 
 
 /*

+ 15 - 0
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'