/* ** check whether, in an assignment to a local variable, the local variable ** is needed in a previous assignment (to a table). If so, save original ** local value in a safe place and use this safe copy in the previous ** assignment. */ private static void check_conflict(LexState ls, LHS_assign lh, expdesc v) { FuncState fs = ls.fs; int extra = fs.freereg; /* eventual position to save local variable */ int conflict = 0; for (; lh!=null; lh = lh.prev) { if (lh.v.k == expkind.VINDEXED) { if (lh.v.u.s.info == v.u.s.info) { /* conflict? */ conflict = 1; lh.v.u.s.info = extra; /* previous assignment will use safe copy */ } if (lh.v.u.s.aux == v.u.s.info) { /* conflict? */ conflict = 1; lh.v.u.s.aux = extra; /* previous assignment will use safe copy */ } } } if (conflict != 0) { LuaKCodeABC(fs, OpCode.OP_MOVE, fs.freereg, v.u.s.info, 0); /* make copy */ LuaKReserveRegs(fs, 1); } }
private static void exprstat(LexState ls) { /* stat . func | assignment */ FuncState fs = ls.fs; LHS_assign v = new LHS_assign(); primaryexp(ls, v.v); if (v.v.k == expkind.VCALL) /* stat . func */ SETARG_C(GetCode(fs, v.v), 1); /* call statement uses no results */ else { /* stat . assignment */ v.prev = null; assignment(ls, v, 1); } }
private static void assignment(LexState ls, LHS_assign lh, int nvars) { expdesc e = new expdesc(); check_condition(ls, expkind.VLOCAL <= lh.v.k && lh.v.k <= expkind.VINDEXED, "syntax error"); if (testnext(ls, ',') != 0) { /* assignment . `,' primaryexp assignment */ LHS_assign nv = new LHS_assign(); nv.prev = lh; primaryexp(ls, nv.v); if (nv.v.k == expkind.VLOCAL) check_conflict(ls, lh, nv.v); luaY_checklimit(ls.fs, nvars, LUAI_MAXCCALLS - ls.L.nCcalls, "variables in assignment"); assignment(ls, nv, nvars+1); } else { /* assignment . `=' explist1 */ int nexps; checknext(ls, '='); nexps = explist1(ls, e); if (nexps != nvars) { adjust_assign(ls, nvars, nexps, e); if (nexps > nvars) ls.fs.freereg -= nexps - nvars; /* remove extra values */ } else { LuaKSetOneRet(ls.fs, e); /* close last expression */ LuaKStoreVar(ls.fs, lh.v, e); return; /* avoid default */ } } init_exp(e, expkind.VNONRELOC, ls.fs.freereg - 1); /* default assignment */ LuaKStoreVar(ls.fs, lh.v, e); }