aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-07-07 13:27:29 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-07-07 13:27:29 -0300
commit81dd13f4c6a70f08d83f7b7360e4e15cf79dd573 (patch)
treeb379d2c248dd57e71f9461db581c6d0cfa0f24f8 /lparser.c
parent6a02bbe1e2f8ad1b98a077bd2aac44e776fd107c (diff)
downloadlua-81dd13f4c6a70f08d83f7b7360e4e15cf79dd573.tar.gz
lua-81dd13f4c6a70f08d83f7b7360e4e15cf79dd573.tar.bz2
lua-81dd13f4c6a70f08d83f7b7360e4e15cf79dd573.zip
new way to distinguish between indexing tables in registers and
tables in upvalues (+ fixed small bug when checking conflicts in multiple assignments)
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/lparser.c b/lparser.c
index c0bf6316..49fe8d8c 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.88 2010/06/21 16:30:12 roberto Exp roberto $ 2** $Id: lparser.c,v 2.89 2010/07/02 20:42:40 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*/
@@ -969,26 +969,25 @@ struct LHS_assign {
969** local value in a safe place and use this safe copy in the previous 969** local value in a safe place and use this safe copy in the previous
970** assignment. 970** assignment.
971*/ 971*/
972static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v, 972static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
973 expkind ix, OpCode op) {
974 FuncState *fs = ls->fs; 973 FuncState *fs = ls->fs;
975 int extra = fs->freereg; /* eventual position to save local variable */ 974 int extra = fs->freereg; /* eventual position to save local variable */
976 int conflict = 0; 975 int conflict = 0;
977 for (; lh; lh = lh->prev) { 976 for (; lh; lh = lh->prev) {
978 if (lh->v.k == ix) { 977 /* conflict in table 't'? */
979 if (lh->v.u.ind.t == v->u.info) { /* conflict? */ 978 if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
980 conflict = 1; 979 conflict = 1;
981 lh->v.k = VINDEXED; 980 lh->v.u.ind.vt = VLOCAL;
982 lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ 981 lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
983 } 982 }
984 if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { /* conflict? */ 983 /* conflict in index 'idx'? */
985 conflict = 1; 984 if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
986 lua_assert(lh->v.k == VINDEXED); 985 conflict = 1;
987 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ 986 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
988 }
989 } 987 }
990 } 988 }
991 if (conflict) { 989 if (conflict) {
990 OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
992 luaK_codeABC(fs, op, fs->freereg, v->u.info, 0); /* make copy */ 991 luaK_codeABC(fs, op, fs->freereg, v->u.info, 0); /* make copy */
993 luaK_reserveregs(fs, 1); 992 luaK_reserveregs(fs, 1);
994 } 993 }
@@ -997,16 +996,13 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v,
997 996
998static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 997static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
999 expdesc e; 998 expdesc e;
1000 check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXEDUP, 999 check_condition(ls, vkisvar(lh->v.k), "syntax error");
1001 "syntax error");
1002 if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ 1000 if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
1003 struct LHS_assign nv; 1001 struct LHS_assign nv;
1004 nv.prev = lh; 1002 nv.prev = lh;
1005 primaryexp(ls, &nv.v); 1003 primaryexp(ls, &nv.v);
1006 if (nv.v.k == VLOCAL) 1004 if (nv.v.k != VINDEXED)
1007 check_conflict(ls, lh, &nv.v, VINDEXED, OP_MOVE); 1005 check_conflict(ls, lh, &nv.v);
1008 else if (nv.v.k == VUPVAL)
1009 check_conflict(ls, lh, &nv.v, VINDEXEDUP, OP_GETUPVAL);
1010 checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls, 1006 checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls,
1011 "variable names"); 1007 "variable names");
1012 assignment(ls, &nv, nvars+1); 1008 assignment(ls, &nv, nvars+1);