diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-04-28 17:57:45 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-04-28 17:57:45 -0300 |
commit | 502a1d1108d4e3b97e012d2ed9a496fd003b08db (patch) | |
tree | 0d1daa63ebe8af89a35ec5ecbc48f7e055eb0374 /lparser.c | |
parent | 173e41b2ebed59a716d299470de25e50aee3b921 (diff) | |
download | lua-502a1d1108d4e3b97e012d2ed9a496fd003b08db.tar.gz lua-502a1d1108d4e3b97e012d2ed9a496fd003b08db.tar.bz2 lua-502a1d1108d4e3b97e012d2ed9a496fd003b08db.zip |
new opcodes for table access with constant keys (strings and integers)
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 40 |
1 files changed, 24 insertions, 16 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.155 2016/08/01 19:51:24 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.156 2017/04/20 19:53:55 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 | */ |
@@ -647,8 +647,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) { | |||
647 | /* recfield -> (NAME | '['exp1']') = exp1 */ | 647 | /* recfield -> (NAME | '['exp1']') = exp1 */ |
648 | FuncState *fs = ls->fs; | 648 | FuncState *fs = ls->fs; |
649 | int reg = ls->fs->freereg; | 649 | int reg = ls->fs->freereg; |
650 | expdesc key, val; | 650 | expdesc tab, key, val; |
651 | int rkkey; | ||
652 | if (ls->t.token == TK_NAME) { | 651 | if (ls->t.token == TK_NAME) { |
653 | checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); | 652 | checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); |
654 | checkname(ls, &key); | 653 | checkname(ls, &key); |
@@ -657,9 +656,10 @@ static void recfield (LexState *ls, struct ConsControl *cc) { | |||
657 | yindex(ls, &key); | 656 | yindex(ls, &key); |
658 | cc->nh++; | 657 | cc->nh++; |
659 | checknext(ls, '='); | 658 | checknext(ls, '='); |
660 | rkkey = luaK_exp2RK(fs, &key); | 659 | tab = *cc->t; |
660 | luaK_indexed(fs, &tab, &key); | ||
661 | expr(ls, &val); | 661 | expr(ls, &val); |
662 | luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); | 662 | luaK_storevar(fs, &tab, &val); |
663 | fs->freereg = reg; /* free registers */ | 663 | fs->freereg = reg; /* free registers */ |
664 | } | 664 | } |
665 | 665 | ||
@@ -1121,17 +1121,25 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | |||
1121 | int extra = fs->freereg; /* eventual position to save local variable */ | 1121 | int extra = fs->freereg; /* eventual position to save local variable */ |
1122 | int conflict = 0; | 1122 | int conflict = 0; |
1123 | for (; lh; lh = lh->prev) { /* check all previous assignments */ | 1123 | for (; lh; lh = lh->prev) { /* check all previous assignments */ |
1124 | if (lh->v.k == VINDEXED) { /* assigning to a table? */ | 1124 | if (vkisindexed(lh->v.k)) { /* assignment to table field? */ |
1125 | /* table is the upvalue/local being assigned now? */ | 1125 | if (lh->v.k == VINDEXUP) { /* is table an upvalue? */ |
1126 | if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { | 1126 | if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) { |
1127 | conflict = 1; | 1127 | conflict = 1; /* table is the upvalue being assigned now */ |
1128 | lh->v.u.ind.vt = VLOCAL; | 1128 | lh->v.k = VINDEXSTR; |
1129 | lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ | 1129 | lh->v.u.ind.t = extra; /* assignment will use safe copy */ |
1130 | } | ||
1130 | } | 1131 | } |
1131 | /* index is the local being assigned? (index cannot be upvalue) */ | 1132 | else { /* table is a register */ |
1132 | if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { | 1133 | if (v->k == VLOCAL && lh->v.u.ind.t == v->u.info) { |
1133 | conflict = 1; | 1134 | conflict = 1; /* table is the local being assigned now */ |
1134 | lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ | 1135 | lh->v.u.ind.t = extra; /* assignment will use safe copy */ |
1136 | } | ||
1137 | /* is index the local being assigned? */ | ||
1138 | if (lh->v.k == VINDEXED && v->k == VLOCAL && | ||
1139 | lh->v.u.ind.idx == v->u.info) { | ||
1140 | conflict = 1; | ||
1141 | lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ | ||
1142 | } | ||
1135 | } | 1143 | } |
1136 | } | 1144 | } |
1137 | } | 1145 | } |
@@ -1151,7 +1159,7 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | |||
1151 | struct LHS_assign nv; | 1159 | struct LHS_assign nv; |
1152 | nv.prev = lh; | 1160 | nv.prev = lh; |
1153 | suffixedexp(ls, &nv.v); | 1161 | suffixedexp(ls, &nv.v); |
1154 | if (nv.v.k != VINDEXED) | 1162 | if (!vkisindexed(nv.v.k)) |
1155 | check_conflict(ls, lh, &nv.v); | 1163 | check_conflict(ls, lh, &nv.v); |
1156 | checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, | 1164 | checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, |
1157 | "C levels"); | 1165 | "C levels"); |