diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-07-07 13:27:29 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-07-07 13:27:29 -0300 |
commit | 81dd13f4c6a70f08d83f7b7360e4e15cf79dd573 (patch) | |
tree | b379d2c248dd57e71f9461db581c6d0cfa0f24f8 /lparser.c | |
parent | 6a02bbe1e2f8ad1b98a077bd2aac44e776fd107c (diff) | |
download | lua-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.c | 36 |
1 files changed, 16 insertions, 20 deletions
@@ -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 | */ |
972 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v, | 972 | static 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 | ||
998 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | 997 | static 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); |