aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/lparser.c b/lparser.c
index a42c6401..8984bc79 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.74 2010/01/05 18:46:58 roberto Exp roberto $ 2** $Id: lparser.c,v 2.75 2010/01/06 11:48:02 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*/
@@ -452,7 +452,7 @@ static void fieldsel (LexState *ls, expdesc *v) {
452 /* fieldsel -> ['.' | ':'] NAME */ 452 /* fieldsel -> ['.' | ':'] NAME */
453 FuncState *fs = ls->fs; 453 FuncState *fs = ls->fs;
454 expdesc key; 454 expdesc key;
455 luaK_exp2anyreg(fs, v); 455 luaK_exp2anyregup(fs, v);
456 luaX_next(ls); /* skip the dot or colon */ 456 luaX_next(ls); /* skip the dot or colon */
457 checkname(ls, &key); 457 checkname(ls, &key);
458 luaK_indexed(fs, v, &key); 458 luaK_indexed(fs, v, &key);
@@ -747,7 +747,7 @@ static void primaryexp (LexState *ls, expdesc *v) {
747 } 747 }
748 case '[': { /* `[' exp1 `]' */ 748 case '[': { /* `[' exp1 `]' */
749 expdesc key; 749 expdesc key;
750 luaK_exp2anyreg(fs, v); 750 luaK_exp2anyregup(fs, v);
751 yindex(ls, &key); 751 yindex(ls, &key);
752 luaK_indexed(fs, v, &key); 752 luaK_indexed(fs, v, &key);
753 break; 753 break;
@@ -951,24 +951,27 @@ struct LHS_assign {
951** local value in a safe place and use this safe copy in the previous 951** local value in a safe place and use this safe copy in the previous
952** assignment. 952** assignment.
953*/ 953*/
954static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { 954static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v,
955 expkind ix, OpCode op) {
955 FuncState *fs = ls->fs; 956 FuncState *fs = ls->fs;
956 int extra = fs->freereg; /* eventual position to save local variable */ 957 int extra = fs->freereg; /* eventual position to save local variable */
957 int conflict = 0; 958 int conflict = 0;
958 for (; lh; lh = lh->prev) { 959 for (; lh; lh = lh->prev) {
959 if (lh->v.k == VINDEXED) { 960 if (lh->v.k == ix) {
960 if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ 961 if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
961 conflict = 1; 962 conflict = 1;
963 lh->v.k = VINDEXED;
962 lh->v.u.s.info = extra; /* previous assignment will use safe copy */ 964 lh->v.u.s.info = extra; /* previous assignment will use safe copy */
963 } 965 }
964 if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ 966 if (v->k == VLOCAL && lh->v.u.s.aux == v->u.s.info) { /* conflict? */
965 conflict = 1; 967 conflict = 1;
968 lua_assert(lh->v.k == VINDEXED);
966 lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ 969 lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
967 } 970 }
968 } 971 }
969 } 972 }
970 if (conflict) { 973 if (conflict) {
971 luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ 974 luaK_codeABC(fs, op, fs->freereg, v->u.s.info, 0); /* make copy */
972 luaK_reserveregs(fs, 1); 975 luaK_reserveregs(fs, 1);
973 } 976 }
974} 977}
@@ -976,14 +979,16 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
976 979
977static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 980static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
978 expdesc e; 981 expdesc e;
979 check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, 982 check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXEDUP,
980 "syntax error"); 983 "syntax error");
981 if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ 984 if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
982 struct LHS_assign nv; 985 struct LHS_assign nv;
983 nv.prev = lh; 986 nv.prev = lh;
984 primaryexp(ls, &nv.v); 987 primaryexp(ls, &nv.v);
985 if (nv.v.k == VLOCAL) 988 if (nv.v.k == VLOCAL)
986 check_conflict(ls, lh, &nv.v); 989 check_conflict(ls, lh, &nv.v, VINDEXED, OP_MOVE);
990 else if (nv.v.k == VUPVAL)
991 check_conflict(ls, lh, &nv.v, VINDEXEDUP, OP_GETUPVAL);
987 checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls, 992 checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls,
988 "variable names"); 993 "variable names");
989 assignment(ls, &nv, nvars+1); 994 assignment(ls, &nv, nvars+1);