summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c20
-rw-r--r--llex.c15
-rw-r--r--llex.h3
-rw-r--r--lparser.c45
-rw-r--r--lparser.h3
-rw-r--r--ltable.h7
6 files changed, 47 insertions, 46 deletions
diff --git a/lcode.c b/lcode.c
index 7a9cb6fb..4dd823f2 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.70 2013/06/20 17:37:31 roberto Exp roberto $ 2** $Id: lcode.c,v 2.71 2013/06/25 18:57:18 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -307,17 +307,21 @@ static void freeexp (FuncState *fs, expdesc *e) {
307} 307}
308 308
309 309
310/*
311** Use scanner's table to cache position of constants in contant list
312** and try to reuse constants
313*/
310static int addk (FuncState *fs, TValue *key, TValue *v) { 314static int addk (FuncState *fs, TValue *key, TValue *v) {
311 lua_State *L = fs->ls->L; 315 lua_State *L = fs->ls->L;
312 TValue *idx = luaH_set(L, fs->h, key);
313 Proto *f = fs->f; 316 Proto *f = fs->f;
317 TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */
314 int k, oldsize; 318 int k, oldsize;
315 if (ttisinteger(idx)) { 319 if (ttisinteger(idx)) { /* is there an index there? */
316 k = ivalue(idx); 320 k = ivalue(idx);
317 if (luaV_rawequalobj(&f->k[k], v)) 321 /* correct value? (warning: must distinguish floats from integers!) */
318 return k; 322 if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
319 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); 323 luaV_rawequalobj(&f->k[k], v))
320 go through and create a new entry for this value */ 324 return k; /* reuse index */
321 } 325 }
322 /* constant not found; create a new entry */ 326 /* constant not found; create a new entry */
323 oldsize = f->sizek; 327 oldsize = f->sizek;
@@ -377,7 +381,7 @@ static int nilK (FuncState *fs) {
377 TValue k, v; 381 TValue k, v;
378 setnilvalue(&v); 382 setnilvalue(&v);
379 /* cannot use nil as key; instead use table itself to represent nil */ 383 /* cannot use nil as key; instead use table itself to represent nil */
380 sethvalue(fs->ls->L, &k, fs->h); 384 sethvalue(fs->ls->L, &k, fs->ls->h);
381 return addk(fs, &k, &v); 385 return addk(fs, &k, &v);
382} 386}
383 387
diff --git a/llex.c b/llex.c
index d1aff60c..7afe31b1 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 2.67 2013/06/19 14:27:00 roberto Exp roberto $ 2** $Id: llex.c,v 2.68 2013/08/21 20:09:51 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -119,22 +119,25 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
119 119
120 120
121/* 121/*
122** creates a new string and anchors it in function's table so that 122** creates a new string and anchors it in scanner's table so that
123** it will not be collected until the end of the function's compilation 123** it will not be collected until the end of the compilation
124** (by that time it should be anchored in function's prototype) 124** (by that time it should be anchored somewhere)
125*/ 125*/
126TString *luaX_newstring (LexState *ls, const char *str, size_t l) { 126TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
127 lua_State *L = ls->L; 127 lua_State *L = ls->L;
128 TValue *o; /* entry for `str' */ 128 TValue *o; /* entry for `str' */
129 TString *ts = luaS_newlstr(L, str, l); /* create new string */ 129 TString *ts = luaS_newlstr(L, str, l); /* create new string */
130 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ 130 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
131 o = luaH_set(L, ls->fs->h, L->top - 1); 131 o = luaH_set(L, ls->h, L->top - 1);
132 if (ttisnil(o)) { /* not in use yet? (see 'addK') */ 132 if (ttisnil(o)) { /* not in use yet? */
133 /* boolean value does not need GC barrier; 133 /* boolean value does not need GC barrier;
134 table has no metatable, so it does not need to invalidate cache */ 134 table has no metatable, so it does not need to invalidate cache */
135 setbvalue(o, 1); /* t[string] = true */ 135 setbvalue(o, 1); /* t[string] = true */
136 luaC_checkGC(L); 136 luaC_checkGC(L);
137 } 137 }
138 else { /* string already present */
139 ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */
140 }
138 L->top--; /* remove string from stack */ 141 L->top--; /* remove string from stack */
139 return ts; 142 return ts;
140} 143}
diff --git a/llex.h b/llex.h
index d1667ad7..e9c1ed99 100644
--- a/llex.h
+++ b/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.h,v 1.73 2013/04/16 18:46:28 roberto Exp roberto $ 2** $Id: llex.h,v 1.74 2013/04/26 13:07:53 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -60,6 +60,7 @@ typedef struct LexState {
60 struct lua_State *L; 60 struct lua_State *L;
61 ZIO *z; /* input stream */ 61 ZIO *z; /* input stream */
62 Mbuffer *buff; /* buffer for tokens */ 62 Mbuffer *buff; /* buffer for tokens */
63 Table *h; /* to avoid collection/reuse strings */
63 struct Dyndata *dyd; /* dynamic structures used by the parser */ 64 struct Dyndata *dyd; /* dynamic structures used by the parser */
64 TString *source; /* current source name */ 65 TString *source; /* current source name */
65 TString *envn; /* environment variable name */ 66 TString *envn; /* environment variable name */
diff --git a/lparser.c b/lparser.c
index c2386b82..0f53ff7c 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.133 2013/04/26 13:07:53 roberto Exp roberto $ 2** $Id: lparser.c,v 2.134 2013/08/16 18:55:49 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -35,6 +35,10 @@
35#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) 35#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
36 36
37 37
38/* because all strings are unified by the scanner, the parser
39 can use pointer equality for string equality */
40#define eqstr(a,b) ((a) == (b))
41
38 42
39/* 43/*
40** nodes for block list (list of active blocks) 44** nodes for block list (list of active blocks)
@@ -57,16 +61,6 @@ static void statement (LexState *ls);
57static void expr (LexState *ls, expdesc *v); 61static void expr (LexState *ls, expdesc *v);
58 62
59 63
60static void anchor_token (LexState *ls) {
61 /* last token from outer function must be EOS */
62 lua_assert(ls->fs != NULL || ls->t.token == TK_EOS);
63 if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
64 TString *ts = ls->t.seminfo.ts;
65 luaX_newstring(ls, getstr(ts), ts->tsv.len);
66 }
67}
68
69
70/* semantic error */ 64/* semantic error */
71static l_noret semerror (LexState *ls, const char *msg) { 65static l_noret semerror (LexState *ls, const char *msg) {
72 ls->t.token = 0; /* remove 'near to' from final message */ 66 ls->t.token = 0; /* remove 'near to' from final message */
@@ -222,7 +216,7 @@ static int searchupvalue (FuncState *fs, TString *name) {
222 int i; 216 int i;
223 Upvaldesc *up = fs->f->upvalues; 217 Upvaldesc *up = fs->f->upvalues;
224 for (i = 0; i < fs->nups; i++) { 218 for (i = 0; i < fs->nups; i++) {
225 if (luaS_eqstr(up[i].name, name)) return i; 219 if (eqstr(up[i].name, name)) return i;
226 } 220 }
227 return -1; /* not found */ 221 return -1; /* not found */
228} 222}
@@ -246,7 +240,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
246static int searchvar (FuncState *fs, TString *n) { 240static int searchvar (FuncState *fs, TString *n) {
247 int i; 241 int i;
248 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { 242 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
249 if (luaS_eqstr(n, getlocvar(fs, i)->varname)) 243 if (eqstr(n, getlocvar(fs, i)->varname))
250 return i; 244 return i;
251 } 245 }
252 return -1; /* not found */ 246 return -1; /* not found */
@@ -342,7 +336,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) {
342 FuncState *fs = ls->fs; 336 FuncState *fs = ls->fs;
343 Labellist *gl = &ls->dyd->gt; 337 Labellist *gl = &ls->dyd->gt;
344 Labeldesc *gt = &gl->arr[g]; 338 Labeldesc *gt = &gl->arr[g];
345 lua_assert(luaS_eqstr(gt->name, label->name)); 339 lua_assert(eqstr(gt->name, label->name));
346 if (gt->nactvar < label->nactvar) { 340 if (gt->nactvar < label->nactvar) {
347 TString *vname = getlocvar(fs, gt->nactvar)->varname; 341 TString *vname = getlocvar(fs, gt->nactvar)->varname;
348 const char *msg = luaO_pushfstring(ls->L, 342 const char *msg = luaO_pushfstring(ls->L,
@@ -369,7 +363,7 @@ static int findlabel (LexState *ls, int g) {
369 /* check labels in current block for a match */ 363 /* check labels in current block for a match */
370 for (i = bl->firstlabel; i < dyd->label.n; i++) { 364 for (i = bl->firstlabel; i < dyd->label.n; i++) {
371 Labeldesc *lb = &dyd->label.arr[i]; 365 Labeldesc *lb = &dyd->label.arr[i];
372 if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ 366 if (eqstr(lb->name, gt->name)) { /* correct label? */
373 if (gt->nactvar > lb->nactvar && 367 if (gt->nactvar > lb->nactvar &&
374 (bl->upval || dyd->label.n > bl->firstlabel)) 368 (bl->upval || dyd->label.n > bl->firstlabel))
375 luaK_patchclose(ls->fs, gt->pc, lb->nactvar); 369 luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
@@ -403,7 +397,7 @@ static void findgotos (LexState *ls, Labeldesc *lb) {
403 Labellist *gl = &ls->dyd->gt; 397 Labellist *gl = &ls->dyd->gt;
404 int i = ls->fs->bl->firstgoto; 398 int i = ls->fs->bl->firstgoto;
405 while (i < gl->n) { 399 while (i < gl->n) {
406 if (luaS_eqstr(gl->arr[i].name, lb->name)) 400 if (eqstr(gl->arr[i].name, lb->name))
407 closegoto(ls, i, lb); 401 closegoto(ls, i, lb);
408 else 402 else
409 i++; 403 i++;
@@ -525,7 +519,6 @@ static void codeclosure (LexState *ls, expdesc *v) {
525 519
526 520
527static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { 521static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
528 lua_State *L = ls->L;
529 Proto *f; 522 Proto *f;
530 fs->prev = ls->fs; /* linked list of funcstates */ 523 fs->prev = ls->fs; /* linked list of funcstates */
531 fs->ls = ls; 524 fs->ls = ls;
@@ -544,10 +537,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
544 f = fs->f; 537 f = fs->f;
545 f->source = ls->source; 538 f->source = ls->source;
546 f->maxstacksize = 2; /* registers 0/1 are always valid */ 539 f->maxstacksize = 2; /* registers 0/1 are always valid */
547 fs->h = luaH_new(L);
548 /* anchor table of constants (to avoid being collected) */
549 sethvalue2s(L, L->top, fs->h);
550 incr_top(L);
551 enterblock(fs, bl, 0); 540 enterblock(fs, bl, 0);
552} 541}
553 542
@@ -572,9 +561,6 @@ static void close_func (LexState *ls) {
572 f->sizeupvalues = fs->nups; 561 f->sizeupvalues = fs->nups;
573 lua_assert(fs->bl == NULL); 562 lua_assert(fs->bl == NULL);
574 ls->fs = fs->prev; 563 ls->fs = fs->prev;
575 /* last token read was anchored in defunct function; must re-anchor it */
576 anchor_token(ls);
577 L->top--; /* pop table of constants */
578 luaC_checkGC(L); 564 luaC_checkGC(L);
579} 565}
580 566
@@ -1202,7 +1188,7 @@ static void gotostat (LexState *ls, int pc) {
1202static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { 1188static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
1203 int i; 1189 int i;
1204 for (i = fs->bl->firstlabel; i < ll->n; i++) { 1190 for (i = fs->bl->firstlabel; i < ll->n; i++) {
1205 if (luaS_eqstr(label, ll->arr[i].name)) { 1191 if (eqstr(label, ll->arr[i].name)) {
1206 const char *msg = luaO_pushfstring(fs->ls->L, 1192 const char *msg = luaO_pushfstring(fs->ls->L,
1207 "label " LUA_QS " already defined on line %d", 1193 "label " LUA_QS " already defined on line %d",
1208 getstr(label), ll->arr[i].line); 1194 getstr(label), ll->arr[i].line);
@@ -1627,8 +1613,10 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1627 LexState lexstate; 1613 LexState lexstate;
1628 FuncState funcstate; 1614 FuncState funcstate;
1629 Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ 1615 Closure *cl = luaF_newLclosure(L, 1); /* create main closure */
1630 /* anchor closure (to avoid being collected) */ 1616 setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */
1631 setclLvalue(L, L->top, cl); 1617 incr_top(L);
1618 lexstate.h = luaH_new(L); /* create table for scanner */
1619 sethvalue(L, L->top, lexstate.h); /* anchor it */
1632 incr_top(L); 1620 incr_top(L);
1633 funcstate.f = cl->l.p = luaF_newproto(L); 1621 funcstate.f = cl->l.p = luaF_newproto(L);
1634 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ 1622 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
@@ -1641,6 +1629,7 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1641 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); 1629 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
1642 /* all scopes should be correctly finished */ 1630 /* all scopes should be correctly finished */
1643 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); 1631 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
1644 return cl; /* it's on the stack too */ 1632 L->top--; /* remove scanner's table */
1633 return cl; /* closure is on the stack, too */
1645} 1634}
1646 1635
diff --git a/lparser.h b/lparser.h
index 41f3c42b..c6a78a79 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.70 2012/05/08 13:53:33 roberto Exp roberto $ 2** $Id: lparser.h,v 1.71 2013/04/16 18:46:28 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -97,7 +97,6 @@ struct BlockCnt; /* defined in lparser.c */
97/* state needed to generate code for a given function */ 97/* state needed to generate code for a given function */
98typedef struct FuncState { 98typedef struct FuncState {
99 Proto *f; /* current function header */ 99 Proto *f; /* current function header */
100 Table *h; /* table to find (and reuse) elements in `k' */
101 struct FuncState *prev; /* enclosing function */ 100 struct FuncState *prev; /* enclosing function */
102 struct LexState *ls; /* lexical state */ 101 struct LexState *ls; /* lexical state */
103 struct BlockCnt *bl; /* chain of current blocks */ 102 struct BlockCnt *bl; /* chain of current blocks */
diff --git a/ltable.h b/ltable.h
index a6dc17d9..f377c009 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 2.16 2011/08/17 20:26:47 roberto Exp roberto $ 2** $Id: ltable.h,v 2.17 2013/04/26 15:39:25 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -18,6 +18,11 @@
18#define invalidateTMcache(t) ((t)->flags = 0) 18#define invalidateTMcache(t) ((t)->flags = 0)
19 19
20 20
21/* returns the key, given the value of a table entry */
22#define keyfromval(v) \
23 (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
24
25
21LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 26LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
22LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 27LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
23 TValue *value); 28 TValue *value);