aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-10-25 17:14:14 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-10-25 17:14:14 -0200
commit21aa7e55f2333e57b972aa4ef2c5e2785d609578 (patch)
treebdd6119f0fab0178979202bc5d0afbd6f4410469 /lparser.c
parentfffb6f3814084cddd8a58e81ae1b73ed78ea0953 (diff)
downloadlua-21aa7e55f2333e57b972aa4ef2c5e2785d609578.tar.gz
lua-21aa7e55f2333e57b972aa4ef2c5e2785d609578.tar.bz2
lua-21aa7e55f2333e57b972aa4ef2c5e2785d609578.zip
optimization for array part of a Table
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/lparser.c b/lparser.c
index b83f5d19..744c9ce6 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.157 2001/09/25 17:06:48 roberto Exp $ 2** $Id: lparser.c,v 1.159 2001/10/02 16:41:36 roberto Exp $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -30,7 +30,8 @@
30** or empty (k = `;' or `}') 30** or empty (k = `;' or `}')
31*/ 31*/
32typedef struct Constdesc { 32typedef struct Constdesc {
33 int n; 33 int narray;
34 int nhash;
34 int k; 35 int k;
35} Constdesc; 36} Constdesc;
36 37
@@ -315,7 +316,7 @@ static void open_func (LexState *ls, FuncState *fs) {
315 fs->jlt = NO_JUMP; 316 fs->jlt = NO_JUMP;
316 fs->freereg = 0; 317 fs->freereg = 0;
317 fs->nk = 0; 318 fs->nk = 0;
318 fs->h = luaH_new(ls->L, 0); 319 fs->h = luaH_new(ls->L, 0, 0);
319 fs->np = 0; 320 fs->np = 0;
320 fs->nlineinfo = 0; 321 fs->nlineinfo = 0;
321 fs->nlocvars = 0; 322 fs->nlocvars = 0;
@@ -507,6 +508,7 @@ static int recfields (LexState *ls, expdesc *t) {
507 int n = 0; 508 int n = 0;
508 do { /* at least one element */ 509 do { /* at least one element */
509 recfield(ls, t); 510 recfield(ls, t);
511 luaX_checklimit(ls, n, MAX_INT, l_s("items in a constructor"));
510 n++; 512 n++;
511 } while (anotherfield(ls)); 513 } while (anotherfield(ls));
512 return n; 514 return n;
@@ -523,8 +525,7 @@ static int listfields (LexState *ls, expdesc *t) {
523 expr(ls, &v); 525 expr(ls, &v);
524 while (anotherfield(ls)) { 526 while (anotherfield(ls)) {
525 luaK_exp2nextreg(fs, &v); 527 luaK_exp2nextreg(fs, &v);
526 luaX_checklimit(ls, n, MAXARG_Bc, 528 luaX_checklimit(ls, n, MAXARG_Bc, l_s("items in a constructor"));
527 l_s("`item groups' in a list initializer"));
528 if (n%LFIELDS_PER_FLUSH == 0) { 529 if (n%LFIELDS_PER_FLUSH == 0) {
529 luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); /* flush */ 530 luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); /* flush */
530 fs->freereg = reg; /* free registers */ 531 fs->freereg = reg; /* free registers */
@@ -548,7 +549,7 @@ static int listfields (LexState *ls, expdesc *t) {
548static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { 549static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) {
549 switch (ls->t.token) { 550 switch (ls->t.token) {
550 case l_c(';'): case l_c('}'): { /* constructor_part -> empty */ 551 case l_c(';'): case l_c('}'): { /* constructor_part -> empty */
551 cd->n = 0; 552 cd->narray = cd->nhash = 0;
552 cd->k = ls->t.token; 553 cd->k = ls->t.token;
553 break; 554 break;
554 } 555 }
@@ -559,13 +560,15 @@ static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) {
559 /* else go through to recfields */ 560 /* else go through to recfields */
560 } 561 }
561 case l_c('['): { /* constructor_part -> recfields */ 562 case l_c('['): { /* constructor_part -> recfields */
562 cd->n = recfields(ls, t); 563 cd->nhash = recfields(ls, t);
564 cd->narray = 0;
563 cd->k = 1; /* record */ 565 cd->k = 1; /* record */
564 break; 566 break;
565 } 567 }
566 default: { /* constructor_part -> listfields */ 568 default: { /* constructor_part -> listfields */
567 case_default: 569 case_default:
568 cd->n = listfields(ls, t); 570 cd->narray = listfields(ls, t);
571 cd->nhash = 0;
569 cd->k = 0; /* list */ 572 cd->k = 0; /* list */
570 break; 573 break;
571 } 574 }
@@ -577,24 +580,27 @@ static void constructor (LexState *ls, expdesc *t) {
577 /* constructor -> `{' constructor_part [`;' constructor_part] `}' */ 580 /* constructor -> `{' constructor_part [`;' constructor_part] `}' */
578 FuncState *fs = ls->fs; 581 FuncState *fs = ls->fs;
579 int line = ls->linenumber; 582 int line = ls->linenumber;
580 int n; 583 int na, nh;
581 int pc; 584 int pc;
582 Constdesc cd; 585 Constdesc cd;
583 pc = luaK_codeABc(fs, OP_NEWTABLE, 0, 0); 586 pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
584 init_exp(t, VRELOCABLE, pc); 587 init_exp(t, VRELOCABLE, pc);
585 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ 588 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
586 check(ls, l_c('{')); 589 check(ls, l_c('{'));
587 constructor_part(ls, t, &cd); 590 constructor_part(ls, t, &cd);
588 n = cd.n; 591 na = cd.narray;
592 nh = cd.nhash;
589 if (optional(ls, l_c(';'))) { 593 if (optional(ls, l_c(';'))) {
590 Constdesc other_cd; 594 Constdesc other_cd;
591 constructor_part(ls, t, &other_cd); 595 constructor_part(ls, t, &other_cd);
592 check_condition(ls, (cd.k != other_cd.k), l_s("invalid constructor syntax")); 596 check_condition(ls,(cd.k != other_cd.k), l_s("invalid constructor syntax"));
593 n += other_cd.n; 597 na += other_cd.narray;
598 nh += other_cd.nhash;
594 } 599 }
595 check_match(ls, l_c('}'), l_c('{'), line); 600 check_match(ls, l_c('}'), l_c('{'), line);
596 luaX_checklimit(ls, n, MAXARG_Bc, l_s("elements in a table constructor")); 601 if (na > 0)
597 SETARG_Bc(fs->f->code[pc], n); /* set initial table size */ 602 SETARG_B(fs->f->code[pc], luaO_log2(na-1)+2); /* set initial table size */
603 SETARG_C(fs->f->code[pc], luaO_log2(nh)+1); /* set initial table size */
598} 604}
599 605
600/* }====================================================================== */ 606/* }====================================================================== */