aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c21
1 files changed, 19 insertions, 2 deletions
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;