** check whether, in an assignment to an upvalue/local variable, the ** upvalue/local variable is begin used in a previous assignment to a ** table. If so, save original upvalue/local value in a safe place and ** use this safe copy in the previous assignment. */
| 1118 | ** use this safe copy in the previous assignment. |
| 1119 | */ |
| 1120 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { |
| 1121 | FuncState *fs = ls->fs; |
| 1122 | int extra = fs->freereg; /* eventual position to save local variable */ |
| 1123 | int conflict = 0; |
| 1124 | for (; lh; lh = lh->prev) { /* check all previous assignments */ |
| 1125 | if (lh->v.k == VINDEXED) { /* assigning to a table? */ |
| 1126 | /* table is the upvalue/local being assigned now? */ |
| 1127 | if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { |
| 1128 | conflict = 1; |
| 1129 | lh->v.u.ind.vt = VLOCAL; |
| 1130 | lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ |
| 1131 | } |
| 1132 | /* index is the local being assigned? (index cannot be upvalue) */ |
| 1133 | if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { |
| 1134 | conflict = 1; |
| 1135 | lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ |
| 1136 | } |
| 1137 | } |
| 1138 | } |
| 1139 | if (conflict) { |
| 1140 | /* copy upvalue/local value to a temporary (in position 'extra') */ |
| 1141 | OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; |
| 1142 | luaK_codeABC(fs, op, extra, v->u.info, 0); |
| 1143 | luaK_reserveregs(fs, 1); |
| 1144 | } |
| 1145 | } |
| 1146 | |
| 1147 | |
| 1148 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { |
no test coverage detected