From 21aa7e55f2333e57b972aa4ef2c5e2785d609578 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 25 Oct 2001 17:14:14 -0200 Subject: optimization for array part of a Table --- lparser.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'lparser.c') diff --git a/lparser.c b/lparser.c index b83f5d19..744c9ce6 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.157 2001/09/25 17:06:48 roberto Exp $ +** $Id: lparser.c,v 1.159 2001/10/02 16:41:36 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -30,7 +30,8 @@ ** or empty (k = `;' or `}') */ typedef struct Constdesc { - int n; + int narray; + int nhash; int k; } Constdesc; @@ -315,7 +316,7 @@ static void open_func (LexState *ls, FuncState *fs) { fs->jlt = NO_JUMP; fs->freereg = 0; fs->nk = 0; - fs->h = luaH_new(ls->L, 0); + fs->h = luaH_new(ls->L, 0, 0); fs->np = 0; fs->nlineinfo = 0; fs->nlocvars = 0; @@ -507,6 +508,7 @@ static int recfields (LexState *ls, expdesc *t) { int n = 0; do { /* at least one element */ recfield(ls, t); + luaX_checklimit(ls, n, MAX_INT, l_s("items in a constructor")); n++; } while (anotherfield(ls)); return n; @@ -523,8 +525,7 @@ static int listfields (LexState *ls, expdesc *t) { expr(ls, &v); while (anotherfield(ls)) { luaK_exp2nextreg(fs, &v); - luaX_checklimit(ls, n, MAXARG_Bc, - l_s("`item groups' in a list initializer")); + luaX_checklimit(ls, n, MAXARG_Bc, l_s("items in a constructor")); if (n%LFIELDS_PER_FLUSH == 0) { luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); /* flush */ fs->freereg = reg; /* free registers */ @@ -548,7 +549,7 @@ static int listfields (LexState *ls, expdesc *t) { static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { switch (ls->t.token) { case l_c(';'): case l_c('}'): { /* constructor_part -> empty */ - cd->n = 0; + cd->narray = cd->nhash = 0; cd->k = ls->t.token; break; } @@ -559,13 +560,15 @@ static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { /* else go through to recfields */ } case l_c('['): { /* constructor_part -> recfields */ - cd->n = recfields(ls, t); + cd->nhash = recfields(ls, t); + cd->narray = 0; cd->k = 1; /* record */ break; } default: { /* constructor_part -> listfields */ case_default: - cd->n = listfields(ls, t); + cd->narray = listfields(ls, t); + cd->nhash = 0; cd->k = 0; /* list */ break; } @@ -577,24 +580,27 @@ static void constructor (LexState *ls, expdesc *t) { /* constructor -> `{' constructor_part [`;' constructor_part] `}' */ FuncState *fs = ls->fs; int line = ls->linenumber; - int n; + int na, nh; int pc; Constdesc cd; - pc = luaK_codeABc(fs, OP_NEWTABLE, 0, 0); + pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); init_exp(t, VRELOCABLE, pc); luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ check(ls, l_c('{')); constructor_part(ls, t, &cd); - n = cd.n; + na = cd.narray; + nh = cd.nhash; if (optional(ls, l_c(';'))) { Constdesc other_cd; constructor_part(ls, t, &other_cd); - check_condition(ls, (cd.k != other_cd.k), l_s("invalid constructor syntax")); - n += other_cd.n; + check_condition(ls,(cd.k != other_cd.k), l_s("invalid constructor syntax")); + na += other_cd.narray; + nh += other_cd.nhash; } check_match(ls, l_c('}'), l_c('{'), line); - luaX_checklimit(ls, n, MAXARG_Bc, l_s("elements in a table constructor")); - SETARG_Bc(fs->f->code[pc], n); /* set initial table size */ + if (na > 0) + SETARG_B(fs->f->code[pc], luaO_log2(na-1)+2); /* set initial table size */ + SETARG_C(fs->f->code[pc], luaO_log2(nh)+1); /* set initial table size */ } /* }====================================================================== */ -- cgit v1.2.3-55-g6feb