aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lcode.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/lcode.c b/lcode.c
index f74223eb..f7c2334c 100644
--- a/lcode.c
+++ b/lcode.c
@@ -842,6 +842,12 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
842 e->k = VRELOC; 842 e->k = VRELOC;
843 break; 843 break;
844 } 844 }
845 case VVARGIND: {
846 freeregs(fs, e->u.ind.t, e->u.ind.idx);
847 e->u.info = luaK_codeABC(fs, OP_GETVARG, 0, e->u.ind.t, e->u.ind.idx);
848 e->k = VRELOC;
849 break;
850 }
845 case VVARARG: case VCALL: { 851 case VVARARG: case VCALL: {
846 luaK_setoneret(fs, e); 852 luaK_setoneret(fs, e);
847 break; 853 break;
@@ -1004,11 +1010,11 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
1004 1010
1005 1011
1006/* 1012/*
1007** Ensures final expression result is either in a register 1013** Ensures final expression result is either in a register,
1008** or in an upvalue. 1014** in an upvalue, or it is the vararg parameter.
1009*/ 1015*/
1010void luaK_exp2anyregup (FuncState *fs, expdesc *e) { 1016void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
1011 if (e->k != VUPVAL || hasjumps(e)) 1017 if ((e->k != VUPVAL && e->k != VVARGVAR) || hasjumps(e))
1012 luaK_exp2anyreg(fs, e); 1018 luaK_exp2anyreg(fs, e);
1013} 1019}
1014 1020
@@ -1314,6 +1320,13 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
1314} 1320}
1315 1321
1316 1322
1323/* auxiliary function to define indexing expressions */
1324static void fillidxk (expdesc *t, int idx, expkind k) {
1325 t->u.ind.idx = cast_byte(idx);
1326 t->k = k;
1327}
1328
1329
1317/* 1330/*
1318** Create expression 't[k]'. 't' must have its final result already in a 1331** Create expression 't[k]'. 't' must have its final result already in a
1319** register or upvalue. Upvalues can only be indexed by literal strings. 1332** register or upvalue. Upvalues can only be indexed by literal strings.
@@ -1325,31 +1338,30 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
1325 if (k->k == VKSTR) 1338 if (k->k == VKSTR)
1326 keystr = str2K(fs, k); 1339 keystr = str2K(fs, k);
1327 lua_assert(!hasjumps(t) && 1340 lua_assert(!hasjumps(t) &&
1328 (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); 1341 (t->k == VLOCAL || t->k == VVARGVAR ||
1342 t->k == VNONRELOC || t->k == VUPVAL));
1329 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ 1343 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */
1330 luaK_exp2anyreg(fs, t); /* put it in a register */ 1344 luaK_exp2anyreg(fs, t); /* put it in a register */
1331 if (t->k == VUPVAL) { 1345 if (t->k == VUPVAL) {
1332 lu_byte temp = cast_byte(t->u.info); /* upvalue index */ 1346 lu_byte temp = cast_byte(t->u.info); /* upvalue index */
1333 t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */ 1347 t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */
1334 lua_assert(isKstr(fs, k)); 1348 lua_assert(isKstr(fs, k));
1335 t->u.ind.idx = cast_short(k->u.info); /* literal short string */ 1349 fillidxk(t, k->u.info, VINDEXUP); /* literal short string */
1336 t->k = VINDEXUP; 1350 }
1351 else if (t->k == VVARGVAR) { /* indexing the vararg parameter? */
1352 lua_assert(t->u.ind.t == fs->f->numparams);
1353 t->u.ind.t = cast_byte(t->u.var.ridx);
1354 fillidxk(t, luaK_exp2anyreg(fs, k), VVARGIND); /* register */
1337 } 1355 }
1338 else { 1356 else {
1339 /* register index of the table */ 1357 /* register index of the table */
1340 t->u.ind.t = cast_byte((t->k == VLOCAL) ? t->u.var.ridx: t->u.info); 1358 t->u.ind.t = cast_byte((t->k == VLOCAL) ? t->u.var.ridx: t->u.info);
1341 if (isKstr(fs, k)) { 1359 if (isKstr(fs, k))
1342 t->u.ind.idx = cast_short(k->u.info); /* literal short string */ 1360 fillidxk(t, k->u.info, VINDEXSTR); /* literal short string */
1343 t->k = VINDEXSTR; 1361 else if (isCint(k)) /* int. constant in proper range? */
1344 } 1362 fillidxk(t, cast_int(k->u.ival), VINDEXI);
1345 else if (isCint(k)) { /* int. constant in proper range? */ 1363 else
1346 t->u.ind.idx = cast_short(k->u.ival); 1364 fillidxk(t, luaK_exp2anyreg(fs, k), VINDEXED); /* register */
1347 t->k = VINDEXI;
1348 }
1349 else {
1350 t->u.ind.idx = cast_short(luaK_exp2anyreg(fs, k)); /* register */
1351 t->k = VINDEXED;
1352 }
1353 } 1365 }
1354 t->u.ind.keystr = keystr; /* string index in 'k' */ 1366 t->u.ind.keystr = keystr; /* string index in 'k' */
1355 t->u.ind.ro = 0; /* by default, not read-only */ 1367 t->u.ind.ro = 0; /* by default, not read-only */
@@ -1913,9 +1925,14 @@ void luaK_finish (FuncState *fs) {
1913 SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */ 1925 SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */
1914 break; 1926 break;
1915 } 1927 }
1916 case OP_JMP: { 1928 case OP_GETVARG: {
1929 if (p->flag & PF_VATAB) /* function has a vararg table? */
1930 SET_OPCODE(*pc, OP_GETTABLE); /* must get vararg there */
1931 break;
1932 }
1933 case OP_JMP: { /* to optimize jumps to jumps */
1917 int target = finaltarget(p->code, i); 1934 int target = finaltarget(p->code, i);
1918 fixjump(fs, i, target); 1935 fixjump(fs, i, target); /* jump directly to final target */
1919 break; 1936 break;
1920 } 1937 }
1921 default: break; 1938 default: break;