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 /lcode.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 'lcode.c')
| -rw-r--r-- | lcode.c | 74 |
1 files changed, 56 insertions, 18 deletions
| @@ -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 | */ |
| 961 | static int isKstr (FuncState *fs, expdesc *e) { | 983 | static 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 | */ |
| 980 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | 1005 | void 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 | ||
