aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-04-28 17:57:45 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-04-28 17:57:45 -0300
commit502a1d1108d4e3b97e012d2ed9a496fd003b08db (patch)
tree0d1daa63ebe8af89a35ec5ecbc48f7e055eb0374 /lcode.c
parent173e41b2ebed59a716d299470de25e50aee3b921 (diff)
downloadlua-502a1d1108d4e3b97e012d2ed9a496fd003b08db.tar.gz
lua-502a1d1108d4e3b97e012d2ed9a496fd003b08db.tar.bz2
lua-502a1d1108d4e3b97e012d2ed9a496fd003b08db.zip
new opcodes for table access with constant keys (strings and integers)
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c74
1 files changed, 56 insertions, 18 deletions
diff --git a/lcode.c b/lcode.c
index ccf7b1ae..a154c339 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.116 2017/04/25 20:01:14 roberto Exp roberto $ 2** $Id: lcode.c,v 2.117 2017/04/26 17:46:52 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -580,18 +580,26 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
580 e->k = VRELOCABLE; 580 e->k = VRELOCABLE;
581 break; 581 break;
582 } 582 }
583 case VINDEXUP: {
584 e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx);
585 e->k = VRELOCABLE;
586 break;
587 }
588 case VINDEXI: {
589 freereg(fs, e->u.ind.t);
590 e->u.info = luaK_codeABC(fs, OP_GETI, 0, e->u.ind.t, e->u.ind.idx);
591 e->k = VRELOCABLE;
592 break;
593 }
594 case VINDEXSTR: {
595 freereg(fs, e->u.ind.t);
596 e->u.info = luaK_codeABC(fs, OP_GETFIELD, 0, e->u.ind.t, e->u.ind.idx);
597 e->k = VRELOCABLE;
598 break;
599 }
583 case VINDEXED: { 600 case VINDEXED: {
584 OpCode op; 601 freeregs(fs, e->u.ind.t, e->u.ind.idx);
585 if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */ 602 e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx);
586 freeregs(fs, e->u.ind.t, e->u.ind.idx);
587 op = OP_GETTABLE;
588 }
589 else {
590 lua_assert(e->u.ind.vt == VUPVAL);
591 freereg(fs, e->u.ind.idx);
592 op = OP_GETTABUP; /* 't' is in an upvalue */
593 }
594 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
595 e->k = VRELOCABLE; 603 e->k = VRELOCABLE;
596 break; 604 break;
597 } 605 }
@@ -807,10 +815,24 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
807 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); 815 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
808 break; 816 break;
809 } 817 }
818 case VINDEXUP: {
819 int e = luaK_exp2RK(fs, ex);
820 luaK_codeABC(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, e);
821 break;
822 }
823 case VINDEXI: {
824 int e = luaK_exp2RK(fs, ex);
825 luaK_codeABC(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, e);
826 break;
827 }
828 case VINDEXSTR: {
829 int e = luaK_exp2RK(fs, ex);
830 luaK_codeABC(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, e);
831 break;
832 }
810 case VINDEXED: { 833 case VINDEXED: {
811 OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
812 int e = luaK_exp2RK(fs, ex); 834 int e = luaK_exp2RK(fs, ex);
813 luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); 835 luaK_codeABC(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, e);
814 break; 836 break;
815 } 837 }
816 default: lua_assert(0); /* invalid var kind to store */ 838 default: lua_assert(0); /* invalid var kind to store */
@@ -959,7 +981,8 @@ static void codenot (FuncState *fs, expdesc *e) {
959** Check whether expression 'e' is a literal string 981** Check whether expression 'e' is a literal string
960*/ 982*/
961static int isKstr (FuncState *fs, expdesc *e) { 983static int isKstr (FuncState *fs, expdesc *e) {
962 return (e->k == VK && ttisstring(&fs->f->k[e->u.info])); 984 return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_C &&
985 ttisstring(&fs->f->k[e->u.info]));
963} 986}
964 987
965 988
@@ -976,15 +999,30 @@ static int isKint (expdesc *e) {
976/* 999/*
977** Create expression 't[k]'. 't' must have its final result already in a 1000** Create expression 't[k]'. 't' must have its final result already in a
978** register or upvalue. Upvalues can only be indexed by literal strings. 1001** register or upvalue. Upvalues can only be indexed by literal strings.
1002** Keys can be literal strings in the constant table or arbitrary
1003** values in registers.
979*/ 1004*/
980void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { 1005void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
981 lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL)); 1006 lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL));
982 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */ 1007 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */
983 luaK_exp2anyreg(fs, t); /* put it in a register */ 1008 luaK_exp2anyreg(fs, t); /* put it in a register */
984 t->u.ind.t = t->u.info; /* register or upvalue index */ 1009 t->u.ind.t = t->u.info; /* register or upvalue index */
985 t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */ 1010 if (t->k == VUPVAL) {
986 t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL; 1011 t->u.ind.idx = k->u.info; /* literal string */
987 t->k = VINDEXED; 1012 t->k = VINDEXUP;
1013 }
1014 else if (isKstr(fs, k)) {
1015 t->u.ind.idx = k->u.info; /* literal string */
1016 t->k = VINDEXSTR;
1017 }
1018 else if (isKint(k)) {
1019 t->u.ind.idx = k->u.ival; /* integer constant */
1020 t->k = VINDEXI;
1021 }
1022 else {
1023 t->u.ind.idx = luaK_exp2anyreg(fs, k); /* register */
1024 t->k = VINDEXED;
1025 }
988} 1026}
989 1027
990 1028