diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-25 17:14:14 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-25 17:14:14 -0200 |
commit | 21aa7e55f2333e57b972aa4ef2c5e2785d609578 (patch) | |
tree | bdd6119f0fab0178979202bc5d0afbd6f4410469 /lparser.c | |
parent | fffb6f3814084cddd8a58e81ae1b73ed78ea0953 (diff) | |
download | lua-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.c | 36 |
1 files changed, 21 insertions, 15 deletions
@@ -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 | */ |
32 | typedef struct Constdesc { | 32 | typedef 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) { | |||
548 | static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { | 549 | static 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 | /* }====================================================================== */ |