aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lcode.c2
-rw-r--r--lopcodes.h3
-rw-r--r--lparser.c21
-rw-r--r--ltests.c1
-rw-r--r--testes/code.lua11
5 files changed, 31 insertions, 7 deletions
diff --git a/lcode.c b/lcode.c
index bc0a3341..a74c2a16 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1804,7 +1804,7 @@ void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) {
1804** table (or LUA_MULTRET to add up to stack top). 1804** table (or LUA_MULTRET to add up to stack top).
1805*/ 1805*/
1806void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { 1806void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
1807 lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); 1807 lua_assert(tostore != 0);
1808 if (tostore == LUA_MULTRET) 1808 if (tostore == LUA_MULTRET)
1809 tostore = 0; 1809 tostore = 0;
1810 if (nelems <= MAXARG_C) 1810 if (nelems <= MAXARG_C)
diff --git a/lopcodes.h b/lopcodes.h
index 235c51f6..1d31e7c5 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -406,7 +406,4 @@ LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];)
406 (((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m)) 406 (((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m))
407 407
408 408
409/* number of list items to accumulate before a SETLIST instruction */
410#define LFIELDS_PER_FLUSH 50
411
412#endif 409#endif
diff --git a/lparser.c b/lparser.c
index cdc8cf42..f3779864 100644
--- a/lparser.c
+++ b/lparser.c
@@ -843,13 +843,13 @@ static void yindex (LexState *ls, expdesc *v) {
843** ======================================================================= 843** =======================================================================
844*/ 844*/
845 845
846
847typedef struct ConsControl { 846typedef struct ConsControl {
848 expdesc v; /* last list item read */ 847 expdesc v; /* last list item read */
849 expdesc *t; /* table descriptor */ 848 expdesc *t; /* table descriptor */
850 int nh; /* total number of 'record' elements */ 849 int nh; /* total number of 'record' elements */
851 int na; /* number of array elements already stored */ 850 int na; /* number of array elements already stored */
852 int tostore; /* number of array elements pending to be stored */ 851 int tostore; /* number of array elements pending to be stored */
852 int maxtostore; /* maximum number of pending elements */
853} ConsControl; 853} ConsControl;
854 854
855 855
@@ -878,7 +878,7 @@ static void closelistfield (FuncState *fs, ConsControl *cc) {
878 if (cc->v.k == VVOID) return; /* there is no list item */ 878 if (cc->v.k == VVOID) return; /* there is no list item */
879 luaK_exp2nextreg(fs, &cc->v); 879 luaK_exp2nextreg(fs, &cc->v);
880 cc->v.k = VVOID; 880 cc->v.k = VVOID;
881 if (cc->tostore == LFIELDS_PER_FLUSH) { 881 if (cc->tostore >= cc->maxtostore) {
882 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ 882 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
883 cc->na += cc->tostore; 883 cc->na += cc->tostore;
884 cc->tostore = 0; /* no more items pending */ 884 cc->tostore = 0; /* no more items pending */
@@ -931,6 +931,22 @@ static void field (LexState *ls, ConsControl *cc) {
931} 931}
932 932
933 933
934/*
935** Compute a limit for how many registers a constructor can use before
936** emitting a 'SETLIST' instruction, based on how many registers are
937** available.
938*/
939static int maxtostore (FuncState *fs) {
940 int numfreeregs = MAX_FSTACK - fs->freereg;
941 if (numfreeregs >= 160) /* "lots" of registers? */
942 return numfreeregs / 5u; /* use up to 1/5 of them */
943 else if (numfreeregs >= 80) /* still "enough" registers? */
944 return 10; /* one 'SETLIST' instruction for each 10 values */
945 else /* save registers for potential more nesting */
946 return 1;
947}
948
949
934static void constructor (LexState *ls, expdesc *t) { 950static void constructor (LexState *ls, expdesc *t) {
935 /* constructor -> '{' [ field { sep field } [sep] ] '}' 951 /* constructor -> '{' [ field { sep field } [sep] ] '}'
936 sep -> ',' | ';' */ 952 sep -> ',' | ';' */
@@ -945,6 +961,7 @@ static void constructor (LexState *ls, expdesc *t) {
945 luaK_reserveregs(fs, 1); 961 luaK_reserveregs(fs, 1);
946 init_exp(&cc.v, VVOID, 0); /* no value (yet) */ 962 init_exp(&cc.v, VVOID, 0); /* no value (yet) */
947 checknext(ls, '{'); 963 checknext(ls, '{');
964 cc.maxtostore = maxtostore(fs);
948 do { 965 do {
949 lua_assert(cc.v.k == VVOID || cc.tostore > 0); 966 lua_assert(cc.v.k == VVOID || cc.tostore > 0);
950 if (ls->t.token == '}') break; 967 if (ls->t.token == '}') break;
diff --git a/ltests.c b/ltests.c
index 1f69fe03..2b8db375 100644
--- a/ltests.c
+++ b/ltests.c
@@ -835,7 +835,6 @@ static int get_limits (lua_State *L) {
835 setnameval(L, "MAXARG_Ax", MAXARG_Ax); 835 setnameval(L, "MAXARG_Ax", MAXARG_Ax);
836 setnameval(L, "MAXARG_Bx", MAXARG_Bx); 836 setnameval(L, "MAXARG_Bx", MAXARG_Bx);
837 setnameval(L, "OFFSET_sBx", OFFSET_sBx); 837 setnameval(L, "OFFSET_sBx", OFFSET_sBx);
838 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
839 setnameval(L, "NUM_OPCODES", NUM_OPCODES); 838 setnameval(L, "NUM_OPCODES", NUM_OPCODES);
840 return 1; 839 return 1;
841} 840}
diff --git a/testes/code.lua b/testes/code.lua
index 329619f1..08b3e23f 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -460,5 +460,16 @@ do -- check number of available registers
460 assert(string.find(msg, "too many registers")) 460 assert(string.find(msg, "too many registers"))
461end 461end
462 462
463
464do -- basic check for SETLIST
465 -- create a list constructor with 50 elements
466 local source = "local a; return {" .. string.rep("a, ", 50) .. "}"
467 local func = assert(load(source))
468 local code = table.concat(T.listcode(func), "\n")
469 local _, count = string.gsub(code, "SETLIST", "")
470 -- code uses only 1 SETLIST for the constructor
471 assert(count == 1)
472end
473
463print 'OK' 474print 'OK'
464 475